<commit_before>
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkImageDecoder.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkStream.h"
#include "SkTemplates.h"
#include "SkPackBits.h"

#include "gif_lib.h"

class SkGIFImageDecoder : public SkImageDecoder {
public:
    virtual Format getFormat() const {
        return kGIF_Format;
    }

protected:
    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
};

static const uint8_t gStartingIterlaceYValue[] = {
    0, 4, 2, 1
};
static const uint8_t gDeltaIterlaceYValue[] = {
    8, 8, 4, 2
};

/*  Implement the GIF interlace algorithm in an iterator.
    1) grab every 8th line beginning at 0
    2) grab every 8th line beginning at 4
    3) grab every 4th line beginning at 2
    4) grab every 2nd line beginning at 1
*/
class GifInterlaceIter {
public:
    GifInterlaceIter(int height) : fHeight(height) {
        fStartYPtr = gStartingIterlaceYValue;
        fDeltaYPtr = gDeltaIterlaceYValue;

        fCurrY = *fStartYPtr++;
        fDeltaY = *fDeltaYPtr++;
    }

    int currY() const {
        SkASSERT(fStartYPtr);
        SkASSERT(fDeltaYPtr);
        return fCurrY;
    }

    void next() {
        SkASSERT(fStartYPtr);
        SkASSERT(fDeltaYPtr);

        int y = fCurrY + fDeltaY;
        // We went from an if statement to a while loop so that we iterate
        // through fStartYPtr until a valid row is found. This is so that images
        // that are smaller than 5x5 will not trash memory.
        while (y >= fHeight) {
            if (gStartingIterlaceYValue +
                    SK_ARRAY_COUNT(gStartingIterlaceYValue) == fStartYPtr) {
                // we done
                SkDEBUGCODE(fStartYPtr = NULL;)
                SkDEBUGCODE(fDeltaYPtr = NULL;)
                y = 0;
            } else {
                y = *fStartYPtr++;
                fDeltaY = *fDeltaYPtr++;
            }
        }
        fCurrY = y;
    }

private:
    const int fHeight;
    int fCurrY;
    int fDeltaY;
    const uint8_t* fStartYPtr;
    const uint8_t* fDeltaYPtr;
};

///////////////////////////////////////////////////////////////////////////////

//#define GIF_STAMP       "GIF"    /* First chars in file - GIF stamp. */
//#define GIF_STAMP_LEN   (sizeof(GIF_STAMP) - 1)

static int DecodeCallBackProc(GifFileType* fileType, GifByteType* out,
                              int size) {
    SkStream* stream = (SkStream*) fileType->UserData;
    return (int) stream->read(out, size);
}

void CheckFreeExtension(SavedImage* Image) {
    if (Image->ExtensionBlocks) {
#if GIFLIB_MAJOR < 5
        FreeExtension(Image);
#else
        GifFreeExtensions(&Image->ExtensionBlockCount, &Image->ExtensionBlocks);
#endif
    }
}

// return NULL on failure
static const ColorMapObject* find_colormap(const GifFileType* gif) {
    const ColorMapObject* cmap = gif->Image.ColorMap;
    if (NULL == cmap) {
        cmap = gif->SColorMap;
    }

    if (NULL == cmap) {
        // no colormap found
        return NULL;
    }
    // some sanity checks
    if (cmap && ((unsigned)cmap->ColorCount > 256 ||
                 cmap->ColorCount != (1 << cmap->BitsPerPixel))) {
        cmap = NULL;
    }
    return cmap;
}

// return -1 if not found (i.e. we're completely opaque)
static int find_transpIndex(const SavedImage& image, int colorCount) {
    int transpIndex = -1;
    for (int i = 0; i < image.ExtensionBlockCount; ++i) {
        const ExtensionBlock* eb = image.ExtensionBlocks + i;
        if (eb->Function == 0xF9 && eb->ByteCount == 4) {
            if (eb->Bytes[0] & 1) {
                transpIndex = (unsigned char)eb->Bytes[3];
                // check for valid transpIndex
                if (transpIndex >= colorCount) {
                    transpIndex = -1;
                }
                break;
            }
        }
    }
    return transpIndex;
}

static bool error_return(GifFileType* gif, const SkBitmap& bm,
                         const char msg[]) {
#if 0
    SkDebugf("libgif error <%s> bitmap [%d %d] pixels %p colortable %p\n",
             msg, bm.width(), bm.height(), bm.getPixels(), bm.getColorTable());
#endif
    return false;
}

bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) {
#if GIFLIB_MAJOR < 5
    GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc);
#else
    GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc, NULL);
#endif
    if (NULL == gif) {
        return error_return(gif, *bm, "DGifOpen");
    }

    SkAutoTCallIProc<GifFileType, DGifCloseFile> acp(gif);

    SavedImage temp_save;
    temp_save.ExtensionBlocks=NULL;
    temp_save.ExtensionBlockCount=0;
    SkAutoTCallVProc<SavedImage, CheckFreeExtension> acp2(&temp_save);

    int width, height;
    GifRecordType recType;
    GifByteType *extData;
#if GIFLIB_MAJOR >= 5
    int extFunction;
#endif
    int transpIndex = -1;   // -1 means we don't have it (yet)

    do {
        if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
            return error_return(gif, *bm, "DGifGetRecordType");
        }

        switch (recType) {
        case IMAGE_DESC_RECORD_TYPE: {
            if (DGifGetImageDesc(gif) == GIF_ERROR) {
                return error_return(gif, *bm, "IMAGE_DESC_RECORD_TYPE");
            }

            if (gif->ImageCount < 1) {    // sanity check
                return error_return(gif, *bm, "ImageCount < 1");
            }

            width = gif->SWidth;
            height = gif->SHeight;
            if (width <= 0 || height <= 0 ||
                !this->chooseFromOneChoice(SkBitmap::kIndex8_Config,
                                           width, height)) {
                return error_return(gif, *bm, "chooseFromOneChoice");
            }

            if (SkImageDecoder::kDecodeBounds_Mode == mode) {
                bm->setConfig(SkBitmap::kIndex8_Config, width, height);
                return true;
            }
#ifdef SK_BUILD_FOR_ANDROID
            // No Bitmap reuse supported for this format
            if (!bm->isNull()) {
                return false;
            }
#endif

            bm->setConfig(SkBitmap::kIndex8_Config, width, height);
            SavedImage* image = &gif->SavedImages[gif->ImageCount-1];
            const GifImageDesc& desc = image->ImageDesc;

            // check for valid descriptor
            if (   (desc.Top | desc.Left) < 0 ||
                    desc.Left + desc.Width > width ||
                    desc.Top + desc.Height > height) {
                return error_return(gif, *bm, "TopLeft");
            }

            // now we decode the colortable
            int colorCount = 0;
            {
                const ColorMapObject* cmap = find_colormap(gif);
                if (NULL == cmap) {
                    return error_return(gif, *bm, "null cmap");
                }

                colorCount = cmap->ColorCount;
                SkColorTable* ctable = SkNEW_ARGS(SkColorTable, (colorCount));
                SkPMColor* colorPtr = ctable->lockColors();
                for (int index = 0; index < colorCount; index++)
                    colorPtr[index] = SkPackARGB32(0xFF,
                                                   cmap->Colors[index].Red,
                                                   cmap->Colors[index].Green,
                                                   cmap->Colors[index].Blue);

                transpIndex = find_transpIndex(temp_save, colorCount);
                if (transpIndex < 0)
                    ctable->setFlags(ctable->getFlags() | SkColorTable::kColorsAreOpaque_Flag);
                else
                    colorPtr[transpIndex] = 0; // ram in a transparent SkPMColor
                ctable->unlockColors(true);

                SkAutoUnref aurts(ctable);
                if (!this->allocPixelRef(bm, ctable)) {
                    return error_return(gif, *bm, "allocPixelRef");
                }
            }

            SkAutoLockPixels alp(*bm);

            // time to decode the scanlines
            //
            uint8_t*  scanline = bm->getAddr8(0, 0);
            const int rowBytes = bm->rowBytes();
            const int innerWidth = desc.Width;
            const int innerHeight = desc.Height;

            // abort if either inner dimension is <= 0
            if (innerWidth <= 0 || innerHeight <= 0) {
                return error_return(gif, *bm, "non-pos inner width/height");
            }

            // are we only a subset of the total bounds?
            if ((desc.Top | desc.Left) > 0 ||
                 innerWidth < width || innerHeight < height)
            {
                int fill;
                if (transpIndex >= 0) {
                    fill = transpIndex;
                } else {
                    fill = gif->SBackGroundColor;
                }
                // check for valid fill index/color
                if (static_cast<unsigned>(fill) >=
                        static_cast<unsigned>(colorCount)) {
                    fill = 0;
                }
                memset(scanline, fill, bm->getSize());
                // bump our starting address
                scanline += desc.Top * rowBytes + desc.Left;
            }

            // now decode each scanline
            if (gif->Image.Interlace)
            {
                GifInterlaceIter iter(innerHeight);
                for (int y = 0; y < innerHeight; y++)
                {
                    uint8_t* row = scanline + iter.currY() * rowBytes;
                    if (DGifGetLine(gif, row, innerWidth) == GIF_ERROR) {
                        return error_return(gif, *bm, "interlace DGifGetLine");
                    }
                    iter.next();
                }
            }
            else
            {
                // easy, non-interlace case
                for (int y = 0; y < innerHeight; y++) {
                    if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) {
                        return error_return(gif, *bm, "DGifGetLine");
                    }
                    scanline += rowBytes;
                }
            }
            goto DONE;
            } break;

        case EXTENSION_RECORD_TYPE:
#if GIFLIB_MAJOR < 5
            if (DGifGetExtension(gif, &temp_save.Function,
                                 &extData) == GIF_ERROR) {
#else
            if (DGifGetExtension(gif, &extFunction, &extData) == GIF_ERROR) {
#endif
                return error_return(gif, *bm, "DGifGetExtension");
            }

            while (extData != NULL) {
                /* Create an extension block with our data */
#if GIFLIB_MAJOR < 5
                if (AddExtensionBlock(&temp_save, extData[0],
                                      &extData[1]) == GIF_ERROR) {
#else
                if (GifAddExtensionBlock(&gif->ExtensionBlockCount,
                                         &gif->ExtensionBlocks,
                                         extFunction,
                                         extData[0],
                                         &extData[1]) == GIF_ERROR) {
#endif
                    return error_return(gif, *bm, "AddExtensionBlock");
                }
                if (DGifGetExtensionNext(gif, &extData) == GIF_ERROR) {
                    return error_return(gif, *bm, "DGifGetExtensionNext");
                }
#if GIFLIB_MAJOR < 5
                temp_save.Function = 0;
#endif
            }
            break;

        case TERMINATE_RECORD_TYPE:
            break;

        default:	/* Should be trapped by DGifGetRecordType */
            break;
        }
    } while (recType != TERMINATE_RECORD_TYPE);

DONE:
    return true;
}

///////////////////////////////////////////////////////////////////////////////
DEFINE_DECODER_CREATOR(GIFImageDecoder);
///////////////////////////////////////////////////////////////////////////////

#include "SkTRegistry.h"

static SkImageDecoder* sk_libgif_dfactory(SkStream* stream) {
    char buf[GIF_STAMP_LEN];
    if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
        if (memcmp(GIF_STAMP,   buf, GIF_STAMP_LEN) == 0 ||
                memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 ||
                memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) {
            return SkNEW(SkGIFImageDecoder);
        }
    }
    return NULL;
}

static SkTRegistry<SkImageDecoder*, SkStream*> gReg(sk_libgif_dfactory);
<commit_msg>skia: Fix Codenomicon image open failure.<commit_after>
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkImageDecoder.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkStream.h"
#include "SkTemplates.h"
#include "SkPackBits.h"

#include "gif_lib.h"

class SkGIFImageDecoder : public SkImageDecoder {
public:
    virtual Format getFormat() const {
        return kGIF_Format;
    }

protected:
    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
};

static const uint8_t gStartingIterlaceYValue[] = {
    0, 4, 2, 1
};
static const uint8_t gDeltaIterlaceYValue[] = {
    8, 8, 4, 2
};

/*  Implement the GIF interlace algorithm in an iterator.
    1) grab every 8th line beginning at 0
    2) grab every 8th line beginning at 4
    3) grab every 4th line beginning at 2
    4) grab every 2nd line beginning at 1
*/
class GifInterlaceIter {
public:
    GifInterlaceIter(int height) : fHeight(height) {
        fStartYPtr = gStartingIterlaceYValue;
        fDeltaYPtr = gDeltaIterlaceYValue;

        fCurrY = *fStartYPtr++;
        fDeltaY = *fDeltaYPtr++;
    }

    int currY() const {
        SkASSERT(fStartYPtr);
        SkASSERT(fDeltaYPtr);
        return fCurrY;
    }

    void next() {
        SkASSERT(fStartYPtr);
        SkASSERT(fDeltaYPtr);

        int y = fCurrY + fDeltaY;
        // We went from an if statement to a while loop so that we iterate
        // through fStartYPtr until a valid row is found. This is so that images
        // that are smaller than 5x5 will not trash memory.
        while (y >= fHeight) {
            if (gStartingIterlaceYValue +
                    SK_ARRAY_COUNT(gStartingIterlaceYValue) == fStartYPtr) {
                // we done
                SkDEBUGCODE(fStartYPtr = NULL;)
                SkDEBUGCODE(fDeltaYPtr = NULL;)
                y = 0;
            } else {
                y = *fStartYPtr++;
                fDeltaY = *fDeltaYPtr++;
            }
        }
        fCurrY = y;
    }

private:
    const int fHeight;
    int fCurrY;
    int fDeltaY;
    const uint8_t* fStartYPtr;
    const uint8_t* fDeltaYPtr;
};

///////////////////////////////////////////////////////////////////////////////

//#define GIF_STAMP       "GIF"    /* First chars in file - GIF stamp. */
//#define GIF_STAMP_LEN   (sizeof(GIF_STAMP) - 1)

static int DecodeCallBackProc(GifFileType* fileType, GifByteType* out,
                              int size) {
    SkStream* stream = (SkStream*) fileType->UserData;
    return (int) stream->read(out, size);
}

void CheckFreeExtension(SavedImage* Image) {
    if (Image->ExtensionBlocks) {
#if GIFLIB_MAJOR < 5
        FreeExtension(Image);
#else
        GifFreeExtensions(&Image->ExtensionBlockCount, &Image->ExtensionBlocks);
#endif
    }
}

// return NULL on failure
static const ColorMapObject* find_colormap(const GifFileType* gif) {
    const ColorMapObject* cmap = gif->Image.ColorMap;
    if (NULL == cmap) {
        cmap = gif->SColorMap;
    }

    if (NULL == cmap) {
        // no colormap found
        return NULL;
    }
    // some sanity checks
    if (cmap && ((unsigned)cmap->ColorCount > 256 ||
                 cmap->ColorCount != (1 << cmap->BitsPerPixel))) {
        cmap = NULL;
    }
    return cmap;
}

// return -1 if not found (i.e. we're completely opaque)
static int find_transpIndex(const SavedImage& image, int colorCount) {
    int transpIndex = -1;
    for (int i = 0; i < image.ExtensionBlockCount; ++i) {
        const ExtensionBlock* eb = image.ExtensionBlocks + i;
        if (eb->Function == 0xF9 && eb->ByteCount == 4) {
            if (eb->Bytes[0] & 1) {
                transpIndex = (unsigned char)eb->Bytes[3];
                // check for valid transpIndex
                if (transpIndex >= colorCount) {
                    transpIndex = -1;
                }
                break;
            }
        }
    }
    return transpIndex;
}

static bool error_return(GifFileType* gif, const SkBitmap& bm,
                         const char msg[]) {
#if 0
    SkDebugf("libgif error <%s> bitmap [%d %d] pixels %p colortable %p\n",
             msg, bm.width(), bm.height(), bm.getPixels(), bm.getColorTable());
#endif
    return false;
}

bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) {
#if GIFLIB_MAJOR < 5
    GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc);
#else
    GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc, NULL);
#endif
    if (NULL == gif) {
        return error_return(gif, *bm, "DGifOpen");
    }

    SkAutoTCallIProc<GifFileType, DGifCloseFile> acp(gif);

    SavedImage temp_save;
    temp_save.ExtensionBlocks=NULL;
    temp_save.ExtensionBlockCount=0;
    SkAutoTCallVProc<SavedImage, CheckFreeExtension> acp2(&temp_save);

    int width, height;
    GifRecordType recType;
    GifByteType *extData;
#if GIFLIB_MAJOR >= 5
    int extFunction;
#endif
    int transpIndex = -1;   // -1 means we don't have it (yet)

    do {
        if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
            return error_return(gif, *bm, "DGifGetRecordType");
        }

        switch (recType) {
        case IMAGE_DESC_RECORD_TYPE: {
            if (DGifGetImageDesc(gif) == GIF_ERROR) {
                return error_return(gif, *bm, "IMAGE_DESC_RECORD_TYPE");
            }

            if (gif->ImageCount < 1) {    // sanity check
                return error_return(gif, *bm, "ImageCount < 1");
            }

            width = gif->SWidth;
            height = gif->SHeight;
            if (width <= 0 || height <= 0 ||
                !this->chooseFromOneChoice(SkBitmap::kIndex8_Config,
                                           width, height)) {
                return error_return(gif, *bm, "chooseFromOneChoice");
            }

            if (SkImageDecoder::kDecodeBounds_Mode == mode) {
                bm->setConfig(SkBitmap::kIndex8_Config, width, height);
                return true;
            }
#ifdef SK_BUILD_FOR_ANDROID
            // No Bitmap reuse supported for this format
            if (!bm->isNull()) {
                return false;
            }
#endif

            bm->setConfig(SkBitmap::kIndex8_Config, width, height);
            SavedImage* image = &gif->SavedImages[gif->ImageCount-1];
            const GifImageDesc& desc = image->ImageDesc;

            // check for valid descriptor
            if (   (desc.Top | desc.Left) < 0 ||
                    desc.Left + desc.Width > width ||
                    desc.Top + desc.Height > height) {
                return error_return(gif, *bm, "TopLeft");
            }

            // now we decode the colortable
            int colorCount = 0;
            {
                const ColorMapObject* cmap = find_colormap(gif);
                if (NULL == cmap) {
                    return error_return(gif, *bm, "null cmap");
                }

                colorCount = cmap->ColorCount;
                SkColorTable* ctable = SkNEW_ARGS(SkColorTable, (colorCount));
                SkPMColor* colorPtr = ctable->lockColors();
                for (int index = 0; index < colorCount; index++)
                    colorPtr[index] = SkPackARGB32(0xFF,
                                                   cmap->Colors[index].Red,
                                                   cmap->Colors[index].Green,
                                                   cmap->Colors[index].Blue);

                transpIndex = find_transpIndex(temp_save, colorCount);
                if (transpIndex < 0)
                    ctable->setFlags(ctable->getFlags() | SkColorTable::kColorsAreOpaque_Flag);
                else
                    colorPtr[transpIndex] = 0; // ram in a transparent SkPMColor
                ctable->unlockColors(true);

                SkAutoUnref aurts(ctable);
                if (!this->allocPixelRef(bm, ctable)) {
                    return error_return(gif, *bm, "allocPixelRef");
                }
            }

            SkAutoLockPixels alp(*bm);

            // time to decode the scanlines
            //
            uint8_t*  scanline = bm->getAddr8(0, 0);
            const int rowBytes = bm->rowBytes();
            const int innerWidth = desc.Width;
            const int innerHeight = desc.Height;

            // abort if either inner dimension is <= 0
            if (innerWidth <= 0 || innerHeight <= 0) {
                return error_return(gif, *bm, "non-pos inner width/height");
            }

            // are we only a subset of the total bounds?
            if ((desc.Top | desc.Left) > 0 ||
                 innerWidth < width || innerHeight < height)
            {
                int fill;
                if (transpIndex >= 0) {
                    fill = transpIndex;
                } else {
                    fill = gif->SBackGroundColor;
                }
                // check for valid fill index/color
                if (static_cast<unsigned>(fill) >=
                        static_cast<unsigned>(colorCount)) {
                    fill = 0;
                }
                memset(scanline, fill, bm->getSize());
                // bump our starting address
                scanline += desc.Top * rowBytes + desc.Left;
            }

            // now decode each scanline
            if (gif->Image.Interlace)
            {
                GifInterlaceIter iter(innerHeight);
                for (int y = 0; y < innerHeight; y++)
                {
                    uint8_t* row = scanline + iter.currY() * rowBytes;
                    if (DGifGetLine(gif, row, innerWidth) == GIF_ERROR) {
                        return error_return(gif, *bm, "interlace DGifGetLine");
                    }
                    iter.next();
                }
            }
            else
            {
                // easy, non-interlace case
                for (int y = 0; y < innerHeight; y++) {
                    if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) {
                        return error_return(gif, *bm, "DGifGetLine");
                    }
                    scanline += rowBytes;
                }
            }
        }
        return true;

        case EXTENSION_RECORD_TYPE:
#if GIFLIB_MAJOR < 5
            if (DGifGetExtension(gif, &temp_save.Function,
                                 &extData) == GIF_ERROR) {
#else
            if (DGifGetExtension(gif, &extFunction, &extData) == GIF_ERROR) {
#endif
                return error_return(gif, *bm, "DGifGetExtension");
            }

            while (extData != NULL) {
                /* Create an extension block with our data */
#if GIFLIB_MAJOR < 5
                if (AddExtensionBlock(&temp_save, extData[0],
                                      &extData[1]) == GIF_ERROR) {
#else
                if (GifAddExtensionBlock(&gif->ExtensionBlockCount,
                                         &gif->ExtensionBlocks,
                                         extFunction,
                                         extData[0],
                                         &extData[1]) == GIF_ERROR) {
#endif
                    return error_return(gif, *bm, "AddExtensionBlock");
                }
                if (DGifGetExtensionNext(gif, &extData) == GIF_ERROR) {
                    return error_return(gif, *bm, "DGifGetExtensionNext");
                }
#if GIFLIB_MAJOR < 5
                temp_save.Function = 0;
#endif
            }
            break;

        case TERMINATE_RECORD_TYPE:
            break;

        default:	/* Should be trapped by DGifGetRecordType */
            break;
        }
    } while (recType != TERMINATE_RECORD_TYPE);
    // Return error, since the image descriptor record type is not present
    return error_return(gif, *bm, "no image descriptor");
}

///////////////////////////////////////////////////////////////////////////////
DEFINE_DECODER_CREATOR(GIFImageDecoder);
///////////////////////////////////////////////////////////////////////////////

#include "SkTRegistry.h"

static SkImageDecoder* sk_libgif_dfactory(SkStream* stream) {
    char buf[GIF_STAMP_LEN];
    if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
        if (memcmp(GIF_STAMP,   buf, GIF_STAMP_LEN) == 0 ||
                memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 ||
                memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) {
            return SkNEW(SkGIFImageDecoder);
        }
    }
    return NULL;
}

static SkTRegistry<SkImageDecoder*, SkStream*> gReg(sk_libgif_dfactory);
<|endoftext|>


<commit_before>/****************************************************************************
 * This file is part of Qt AccountsService Addon.
 *
 * Copyright (C) 2012-2013 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
 *
 * Author(s):
 *    Pier Luigi Fiorini
 *
 * $BEGIN_LICENSE:LGPL2.1+$
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $END_LICENSE$
 ***************************************************************************/

#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>

#include <QtAccountsService/accountsmanager.h>
#include <QtAccountsService/useraccount.h>

QT_BEGIN_NAMESPACE

class AccountsServiceDeclarativeModule : public QQmlExtensionPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")

public:
    virtual void registerTypes(const char *uri) {
        Q_ASSERT(QLatin1String(uri) == QLatin1String("QtAccountsService"));

        qmlRegisterType<QtAddOn::AccountsService::AccountsManager>(uri, 5, 0, "AccountsManager");
        qmlRegisterUncreatableType<QtAddOn::AccountsService::UserAccount>(uri, 5, 0, "UserAccount",
                                                                          trUtf8("UserAccount is provided by AccountsManager"));
    }

    void initializeEngine(QQmlEngine *engine, const char *uri) {
        Q_UNUSED(engine);
        Q_UNUSED(uri);
    }
};

QT_END_NAMESPACE

#include "main.moc"
<commit_msg>UserAccount is now a creatable type.<commit_after>/****************************************************************************
 * This file is part of Qt AccountsService Addon.
 *
 * Copyright (C) 2012-2013 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
 *
 * Author(s):
 *    Pier Luigi Fiorini
 *
 * $BEGIN_LICENSE:LGPL2.1+$
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $END_LICENSE$
 ***************************************************************************/

#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>

#include <QtAccountsService/accountsmanager.h>
#include <QtAccountsService/useraccount.h>

QT_BEGIN_NAMESPACE

class AccountsServiceDeclarativeModule : public QQmlExtensionPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")

public:
    virtual void registerTypes(const char *uri) {
        Q_ASSERT(QLatin1String(uri) == QLatin1String("QtAccountsService"));

        qmlRegisterType<QtAddOn::AccountsService::AccountsManager>(uri, 5, 0, "AccountsManager");
        qmlRegisterType<QtAddOn::AccountsService::UserAccount>(uri, 5, 0, "UserAccount");
    }

    void initializeEngine(QQmlEngine *engine, const char *uri) {
        Q_UNUSED(engine);
        Q_UNUSED(uri);
    }
};

QT_END_NAMESPACE

#include "main.moc"
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Milian Wolff <mail@milianw.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "chartmodel.h"

#include <KChartGlobal>
#include <KChartLineAttributes>
#include <KLocalizedString>
#include <KFormat>

#include <QPen>
#include <QBrush>
#include <QDebug>

#include "modeltest.h"

namespace {
QColor colorForColumn(int column, int columnCount)
{
    return QColor::fromHsv((double(column + 1) / columnCount) * 255, 255, 255);
}
}

ChartModel::ChartModel(Type type, QObject* parent)
    : QAbstractTableModel(parent)
    , m_type(type)
{
    qRegisterMetaType<ChartData>();
    new ModelTest(this);
}

ChartModel::~ChartModel() = default;

ChartModel::Type ChartModel::type() const
{
    return m_type;
}

QVariant ChartModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    Q_ASSERT(orientation != Qt::Horizontal || section < columnCount());
    if (orientation == Qt::Horizontal) {
        if (role == KChart::DatasetPenRole) {
            return QVariant::fromValue(QPen(colorForColumn(section, columnCount())));
        } else if (role == KChart::DatasetBrushRole) {
            return QVariant::fromValue(QBrush(colorForColumn(section, columnCount())));
        }

        if (role == Qt::DisplayRole || Qt::ToolTipRole) {
            if (section == 0) {
                return i18n("Elapsed Time");
            }
            switch (m_type) {
            case Allocated:
                return i18n("Memory Allocated");
            case Allocations:
                return i18n("Memory Allocations");
            case Consumed:
                return i18n("Memory Consumed");
            }
        }
    }
    return {};
}

QVariant ChartModel::data(const QModelIndex& index, int role) const
{
    if (!index.isValid()) {
        return {};
    }
    Q_ASSERT(index.row() >= 0 && index.row() < rowCount(index.parent()));
    Q_ASSERT(index.column() >= 0 && index.column() < columnCount(index.parent()));
    Q_ASSERT(!index.parent().isValid());

    if ( role == KChart::LineAttributesRole ) {
        KChart::LineAttributes attributes;
        attributes.setDisplayArea(true);
        if (index.column() > 1) {
            attributes.setTransparency(127);
        } else {
            attributes.setTransparency(50);
        }
        return QVariant::fromValue(attributes);
    }

    if ( role == KChart::DatasetPenRole ) {
        return QVariant::fromValue(QPen(colorForColumn(index.column(), columnCount())));
    } else if ( role == KChart::DatasetBrushRole ) {
        return QVariant::fromValue(QBrush(colorForColumn(index.column(), columnCount())));
    }

    if ( role != Qt::DisplayRole && role != Qt::ToolTipRole ) {
        return {};
    }

    const auto& data = m_data.rows.at(index.row());

    int column = index.column();
    if (role != Qt::ToolTipRole && column % 2 == 0) {
        return data.timeStamp;
    }
    column = column / 2;

    const auto cost = data.cost.value(column);
    if (role == Qt::ToolTipRole) {
        const QString time = QString::number(double(data.timeStamp) / 1000, 'g', 3) + QLatin1Char('s');
        const auto label = m_data.labels.value(column);
        if (m_type == Allocations) {
            return i18n("%1: %2 at %3", label, cost, time);
        } else {
            KFormat format;
            return i18n("%1: %2 at %3", label, format.formatByteSize(cost, 1, KFormat::MetricBinaryDialect), time);
        }
    }

    return cost;
}

int ChartModel::columnCount(const QModelIndex& /*parent*/) const
{
    return m_data.labels.size() * 2;
}

int ChartModel::rowCount(const QModelIndex& parent) const
{
    if (parent.isValid()) {
        return 0;
    } else {
        return m_data.rows.size();
    }
}

void ChartModel::resetData(const ChartData& data)
{
    beginResetModel();
    m_data = data;
    endResetModel();
}
<commit_msg>Disable modeltest.<commit_after>/*
 * Copyright 2015 Milian Wolff <mail@milianw.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "chartmodel.h"

#include <KChartGlobal>
#include <KChartLineAttributes>
#include <KLocalizedString>
#include <KFormat>

#include <QPen>
#include <QBrush>
#include <QDebug>

namespace {
QColor colorForColumn(int column, int columnCount)
{
    return QColor::fromHsv((double(column + 1) / columnCount) * 255, 255, 255);
}
}

ChartModel::ChartModel(Type type, QObject* parent)
    : QAbstractTableModel(parent)
    , m_type(type)
{
    qRegisterMetaType<ChartData>();
}

ChartModel::~ChartModel() = default;

ChartModel::Type ChartModel::type() const
{
    return m_type;
}

QVariant ChartModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    Q_ASSERT(orientation != Qt::Horizontal || section < columnCount());
    if (orientation == Qt::Horizontal) {
        if (role == KChart::DatasetPenRole) {
            return QVariant::fromValue(QPen(colorForColumn(section, columnCount())));
        } else if (role == KChart::DatasetBrushRole) {
            return QVariant::fromValue(QBrush(colorForColumn(section, columnCount())));
        }

        if (role == Qt::DisplayRole || Qt::ToolTipRole) {
            if (section == 0) {
                return i18n("Elapsed Time");
            }
            switch (m_type) {
            case Allocated:
                return i18n("Memory Allocated");
            case Allocations:
                return i18n("Memory Allocations");
            case Consumed:
                return i18n("Memory Consumed");
            }
        }
    }
    return {};
}

QVariant ChartModel::data(const QModelIndex& index, int role) const
{
    if (!index.isValid()) {
        return {};
    }
    Q_ASSERT(index.row() >= 0 && index.row() < rowCount(index.parent()));
    Q_ASSERT(index.column() >= 0 && index.column() < columnCount(index.parent()));
    Q_ASSERT(!index.parent().isValid());

    if ( role == KChart::LineAttributesRole ) {
        KChart::LineAttributes attributes;
        attributes.setDisplayArea(true);
        if (index.column() > 1) {
            attributes.setTransparency(127);
        } else {
            attributes.setTransparency(50);
        }
        return QVariant::fromValue(attributes);
    }

    if ( role == KChart::DatasetPenRole ) {
        return QVariant::fromValue(QPen(colorForColumn(index.column(), columnCount())));
    } else if ( role == KChart::DatasetBrushRole ) {
        return QVariant::fromValue(QBrush(colorForColumn(index.column(), columnCount())));
    }

    if ( role != Qt::DisplayRole && role != Qt::ToolTipRole ) {
        return {};
    }

    const auto& data = m_data.rows.at(index.row());

    int column = index.column();
    if (role != Qt::ToolTipRole && column % 2 == 0) {
        return data.timeStamp;
    }
    column = column / 2;

    const auto cost = data.cost.value(column);
    if (role == Qt::ToolTipRole) {
        const QString time = QString::number(double(data.timeStamp) / 1000, 'g', 3) + QLatin1Char('s');
        const auto label = m_data.labels.value(column);
        if (m_type == Allocations) {
            return i18n("%1: %2 at %3", label, cost, time);
        } else {
            KFormat format;
            return i18n("%1: %2 at %3", label, format.formatByteSize(cost, 1, KFormat::MetricBinaryDialect), time);
        }
    }

    return cost;
}

int ChartModel::columnCount(const QModelIndex& /*parent*/) const
{
    return m_data.labels.size() * 2;
}

int ChartModel::rowCount(const QModelIndex& parent) const
{
    if (parent.isValid()) {
        return 0;
    } else {
        return m_data.rows.size();
    }
}

void ChartModel::resetData(const ChartData& data)
{
    beginResetModel();
    m_data = data;
    endResetModel();
}
<|endoftext|>


<commit_before>#include <aleph/math/Bootstrap.hh>

#include <aleph/persistenceDiagrams/PersistenceDiagram.hh>
#include <aleph/persistenceDiagrams/PersistenceIndicatorFunction.hh>

#include <aleph/persistenceDiagrams/io/Raw.hh>

#include <aleph/utilities/Values.hh>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <string>
#include <vector>

#include <cmath>

#include <getopt.h>

using DataType                     = double;
using PersistenceDiagram           = aleph::PersistenceDiagram<DataType>;
using PersistenceIndicatorFunction = decltype( aleph::persistenceIndicatorFunction( PersistenceDiagram() ) );
using Image                        = PersistenceIndicatorFunction::Image;

auto meanCalculation = [] ( auto begin, auto end )
{
  using T  = typename std::iterator_traits<decltype(begin)>::value_type;
  auto sum = std::accumulate( begin, end, T() );

  if( begin == end )
    return std::numeric_limits<T>::quiet_NaN();

  return sum / static_cast<double>( std::distance(begin, end) );
};

unsigned index( unsigned int samples, double alpha )
{
  // This accounts for rounding and works regardless of whether
  // the product samples * alpha is an integer or not. Note the
  // offset of -1. It is required because, say, the 100th value
  // is at index 99 of the vector.
  return static_cast<unsigned>( std::ceil( samples * alpha ) ) - 1;
}

int main( int argc, char** argv )
{
  auto alpha                   = 0.05;
  unsigned numBootstrapSamples = 50;
  bool readStepFunctions       = false;

  {
    static option commandLineOptions[] =
    {
      { "alpha"              , required_argument, nullptr, 'a' },
      { "bootstrap"          , required_argument, nullptr, 'b' },
      { "read-step-functions", no_argument      , nullptr, 's' },
      { nullptr              , 0                , nullptr,  0  }
    };

    int c = 0;
    while( ( c = getopt_long( argc, argv, "a:b:s", commandLineOptions, nullptr ) ) != -1 )
    {
      switch( c )
      {
      case 'a':
        alpha = std::stod( optarg );
        break;

      case 'b':
        numBootstrapSamples = static_cast<unsigned>( std::stoul( optarg ) );
        break;

      case 's':
        readStepFunctions = true;
        break;

      default:
        throw std::runtime_error( "Unknown command-line parameter" );
      }
    }

    aleph::utilities::ensureRange( alpha, 0.0, 1.0 );
    aleph::utilities::ensureLarger( numBootstrapSamples, unsigned(0) );
  }

  // No input files are present, so let's do nothing at all
  if( argc - optind <= 0 )
    return 0;

  std::vector<PersistenceIndicatorFunction> persistenceIndicatorFunctions;
  persistenceIndicatorFunctions.reserve( static_cast<std::size_t>( argc - optind ) );

  for( int i = optind; i < argc; i++ )
  {
    std::cerr << "* Processing '" << argv[i] << "'...";

    if( readStepFunctions )
    {
      PersistenceIndicatorFunction PIF;

      std::ifstream in( argv[i] );
      if( !in )
        throw std::runtime_error( "Unable to load input file" );

      in >> PIF;
    }
    else
    {
      auto D = aleph::io::load<DataType>( argv[i] );

      D.removeDiagonal();
      D.removeUnpaired();

      persistenceIndicatorFunctions.emplace_back( aleph::persistenceIndicatorFunction( D ) );
    }

    std::cerr << "finished\n";
  }

  std::vector<PersistenceIndicatorFunction> meanReplicates;
  meanReplicates.reserve( numBootstrapSamples );

  aleph::math::Bootstrap bootstrap;

  bootstrap.makeReplicates( numBootstrapSamples,
                            persistenceIndicatorFunctions.begin(), persistenceIndicatorFunctions.end(),
                            meanCalculation,
                            std::back_inserter( meanReplicates ) );

  auto empiricalMean = meanCalculation( persistenceIndicatorFunctions.begin(), persistenceIndicatorFunctions.end() );

  std::vector<Image> theta;
  theta.reserve( numBootstrapSamples );

  for( auto&& meanReplicate: meanReplicates )
  {
    auto n = persistenceIndicatorFunctions.size();
    auto f = std::sqrt( n ) * ( meanReplicate - empiricalMean );
    f      = f.abs();

    theta.emplace_back( f.sup() );
  }

  std::sort( theta.begin(), theta.end() );

  if( theta.empty() )
    return 0;

  auto quantile = theta.at( index( numBootstrapSamples, 1.0 - alpha ) );
  auto fLower   = empiricalMean - quantile / std::sqrt( persistenceIndicatorFunctions.size() );
  auto fUpper   = empiricalMean + quantile / std::sqrt( persistenceIndicatorFunctions.size() );

  std::ofstream out( "/tmp/Mean_plus_confidence.txt" );

  out << empiricalMean << "\n\n"
      << fUpper        << "\n\n"
      << fLower        << "\n";

}
<commit_msg>Storing new PIF<commit_after>#include <aleph/math/Bootstrap.hh>

#include <aleph/persistenceDiagrams/PersistenceDiagram.hh>
#include <aleph/persistenceDiagrams/PersistenceIndicatorFunction.hh>

#include <aleph/persistenceDiagrams/io/Raw.hh>

#include <aleph/utilities/Values.hh>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <string>
#include <vector>

#include <cmath>

#include <getopt.h>

using DataType                     = double;
using PersistenceDiagram           = aleph::PersistenceDiagram<DataType>;
using PersistenceIndicatorFunction = decltype( aleph::persistenceIndicatorFunction( PersistenceDiagram() ) );
using Image                        = PersistenceIndicatorFunction::Image;

auto meanCalculation = [] ( auto begin, auto end )
{
  using T  = typename std::iterator_traits<decltype(begin)>::value_type;
  auto sum = std::accumulate( begin, end, T() );

  if( begin == end )
    return std::numeric_limits<T>::quiet_NaN();

  return sum / static_cast<double>( std::distance(begin, end) );
};

unsigned index( unsigned int samples, double alpha )
{
  // This accounts for rounding and works regardless of whether
  // the product samples * alpha is an integer or not. Note the
  // offset of -1. It is required because, say, the 100th value
  // is at index 99 of the vector.
  return static_cast<unsigned>( std::ceil( samples * alpha ) ) - 1;
}

int main( int argc, char** argv )
{
  auto alpha                   = 0.05;
  unsigned numBootstrapSamples = 50;
  bool readStepFunctions       = false;

  {
    static option commandLineOptions[] =
    {
      { "alpha"              , required_argument, nullptr, 'a' },
      { "bootstrap"          , required_argument, nullptr, 'b' },
      { "read-step-functions", no_argument      , nullptr, 's' },
      { nullptr              , 0                , nullptr,  0  }
    };

    int c = 0;
    while( ( c = getopt_long( argc, argv, "a:b:s", commandLineOptions, nullptr ) ) != -1 )
    {
      switch( c )
      {
      case 'a':
        alpha = std::stod( optarg );
        break;

      case 'b':
        numBootstrapSamples = static_cast<unsigned>( std::stoul( optarg ) );
        break;

      case 's':
        readStepFunctions = true;
        break;

      default:
        throw std::runtime_error( "Unknown command-line parameter" );
      }
    }

    aleph::utilities::ensureRange( alpha, 0.0, 1.0 );
    aleph::utilities::ensureLarger( numBootstrapSamples, unsigned(0) );
  }

  // No input files are present, so let's do nothing at all
  if( argc - optind <= 0 )
    return 0;

  std::vector<PersistenceIndicatorFunction> persistenceIndicatorFunctions;
  persistenceIndicatorFunctions.reserve( static_cast<std::size_t>( argc - optind ) );

  for( int i = optind; i < argc; i++ )
  {
    std::cerr << "* Processing '" << argv[i] << "'...";

    if( readStepFunctions )
    {
      PersistenceIndicatorFunction PIF;

      std::ifstream in( argv[i] );
      if( !in )
        throw std::runtime_error( "Unable to load input file" );

      in >> PIF;

      persistenceIndicatorFunctions.emplace_back( PIF );
    }
    else
    {
      auto D = aleph::io::load<DataType>( argv[i] );

      D.removeDiagonal();
      D.removeUnpaired();

      persistenceIndicatorFunctions.emplace_back( aleph::persistenceIndicatorFunction( D ) );
    }

    std::cerr << "finished\n";
  }

  std::vector<PersistenceIndicatorFunction> meanReplicates;
  meanReplicates.reserve( numBootstrapSamples );

  aleph::math::Bootstrap bootstrap;

  bootstrap.makeReplicates( numBootstrapSamples,
                            persistenceIndicatorFunctions.begin(), persistenceIndicatorFunctions.end(),
                            meanCalculation,
                            std::back_inserter( meanReplicates ) );

  auto empiricalMean = meanCalculation( persistenceIndicatorFunctions.begin(), persistenceIndicatorFunctions.end() );

  std::vector<Image> theta;
  theta.reserve( numBootstrapSamples );

  for( auto&& meanReplicate: meanReplicates )
  {
    auto n = persistenceIndicatorFunctions.size();
    auto f = std::sqrt( n ) * ( meanReplicate - empiricalMean );
    f      = f.abs();

    theta.emplace_back( f.sup() );
  }

  std::sort( theta.begin(), theta.end() );

  if( theta.empty() )
    return 0;

  auto quantile = theta.at( index( numBootstrapSamples, 1.0 - alpha ) );
  auto fLower   = empiricalMean - quantile / std::sqrt( persistenceIndicatorFunctions.size() );
  auto fUpper   = empiricalMean + quantile / std::sqrt( persistenceIndicatorFunctions.size() );

  std::ofstream out( "/tmp/Mean_plus_confidence.txt" );

  out << empiricalMean << "\n\n"
      << fUpper        << "\n\n"
      << fLower        << "\n";

}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 * $Log$
 * Revision 1.7  2003/09/30 21:31:30  peiyongz
 * Implementation of Serialization/Deserialization
 *
 * Revision 1.6  2003/05/18 14:02:07  knoaman
 * Memory manager implementation: pass per instance manager.
 *
 * Revision 1.5  2003/05/16 06:01:57  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.4  2003/05/15 18:53:26  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.3  2002/12/18 14:17:55  gareth
 * Fix to bug #13438. When you eant a vector that calls delete[] on its members you should use RefArrayVectorOf.
 *
 * Revision 1.2  2002/11/04 14:53:27  tng
 * C++ Namespace Support.
 *
 * Revision 1.1.1.1  2002/02/01 22:22:40  peiyongz
 * sane_include
 *
 * Revision 1.10  2001/10/10 14:18:26  peiyongz
 * no message
 *
 * Revision 1.9  2001/10/09 20:53:58  peiyongz
 * init(): take 1 arg.
 *
 * Revision 1.8  2001/10/02 18:59:29  peiyongz
 * Invalid_Facet_Tag to display the tag name
 *
 * Revision 1.7  2001/09/24 15:33:15  peiyongz
 * DTV Reorganization: virtual methods moved to *.cpp
 *
 * Revision 1.6  2001/09/19 18:49:17  peiyongz
 * DTV reorganization: move inline to class declaration to avoid inline
 * function interdependency.
 *
 * Revision 1.5  2001/09/18 20:38:03  peiyongz
 * DTV reorganization: inherit from AbstractStringValidator.
 *
 * Revision 1.4  2001/08/21 18:42:53  peiyongz
 * Bugzilla# 2816: cleanUp() declared with external linkage and called
 *                          before defined as inline
 *
 * Revision 1.3  2001/08/14 22:11:56  peiyongz
 * new exception message added
 *
 * Revision 1.2  2001/08/10 16:21:19  peiyongz
 * use XMLUri instead of XMLURL
 *
 * Revision 1.1  2001/08/01 18:49:16  peiyongz
 * AnyRUIDatatypeValidator
 *
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/validators/datatype/AnyURIDatatypeValidator.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

//
//http://www.template.com
//
static const XMLCh BASE_URI[] =
{
    chLatin_h, chLatin_t, chLatin_t, chLatin_p,
    chColon, chForwardSlash, chForwardSlash,
    chLatin_w, chLatin_w, chLatin_w, chPeriod,
    chLatin_t, chLatin_e, chLatin_m, chLatin_p, chLatin_l,
    chLatin_a, chLatin_t, chLatin_e, chPeriod,
    chLatin_c, chLatin_o, chLatin_m, chNull
};

// ---------------------------------------------------------------------------
//  Constructors and Destructor
// ---------------------------------------------------------------------------
AnyURIDatatypeValidator::AnyURIDatatypeValidator(MemoryManager* const manager)
:AbstractStringValidator(0, 0, 0, DatatypeValidator::AnyURI, manager)
,fTempURI(0)
{}

AnyURIDatatypeValidator::~AnyURIDatatypeValidator()
{
    cleanUp();
}

AnyURIDatatypeValidator::AnyURIDatatypeValidator(
                          DatatypeValidator*            const baseValidator
                        , RefHashTableOf<KVStringPair>* const facets
                        , RefArrayVectorOf<XMLCh>*           const enums
                        , const int                           finalSet
                        , MemoryManager* const manager)
:AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::AnyURI, manager)
,fTempURI(0)
{
    try
    {
        init(enums);
    }
    catch (...)
    {
        cleanUp();
        throw;
    }
}

DatatypeValidator* AnyURIDatatypeValidator::newInstance(
                                      RefHashTableOf<KVStringPair>* const facets
                                    , RefArrayVectorOf<XMLCh>*           const enums
                                    , const int                           finalSet
                                    , MemoryManager* const manager)
{
    return (DatatypeValidator*) new AnyURIDatatypeValidator(this, facets, enums, finalSet, manager);
}

// ---------------------------------------------------------------------------
//  Utilities
// ---------------------------------------------------------------------------

void AnyURIDatatypeValidator::assignAdditionalFacet( const XMLCh* const key
                                                   , const XMLCh* const)
{
    ThrowXML1(InvalidDatatypeFacetException
            , XMLExcepts::FACET_Invalid_Tag
            , key);
}

void AnyURIDatatypeValidator::inheritAdditionalFacet()
{}

void AnyURIDatatypeValidator::checkAdditionalFacetConstraints() const
{}

void AnyURIDatatypeValidator::checkAdditionalFacet(const XMLCh* const) const
{}

int AnyURIDatatypeValidator::getLength(const XMLCh* const content) const
{
    return XMLString::stringLen(content);
}

void AnyURIDatatypeValidator::checkValueSpace(const XMLCh* const content)
{

    // check 3.2.17.c0 must: URI (rfc 2396/2723)
    try
    {
        if (!fTempURI)
            fTempURI = new (fMemoryManager) XMLUri(BASE_URI, fMemoryManager);

        // Support for relative URLs
        // According to Java 1.1: URLs may also be specified with a
        // String and the URL object that it is related to.
        //
        if (XMLString::stringLen(content))
        {
            XMLUri  newURI(fTempURI, content, fMemoryManager);
        }
    }
    catch (...)
    {
        ThrowXML1(InvalidDatatypeValueException
                , XMLExcepts::VALUE_URI_Malformed
                , content);
    }

}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(AnyURIDatatypeValidator)

void AnyURIDatatypeValidator::serialize(XSerializeEngine& serEng)
{
    AbstractStringValidator::serialize(serEng);

    //don't serialize fTempURI
}

XERCES_CPP_NAMESPACE_END

/**
  * End of file AnyURIDatatypeValidator.cpp
  */
<commit_msg>Performance: call a static method to check the validity of URI instead of creating/deleting local objects.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 * $Log$
 * Revision 1.8  2003/10/01 00:27:12  knoaman
 * Performance: call a static method to check the validity of URI instead of
 * creating/deleting local objects.
 *
 * Revision 1.7  2003/09/30 21:31:30  peiyongz
 * Implementation of Serialization/Deserialization
 *
 * Revision 1.6  2003/05/18 14:02:07  knoaman
 * Memory manager implementation: pass per instance manager.
 *
 * Revision 1.5  2003/05/16 06:01:57  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.4  2003/05/15 18:53:26  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.3  2002/12/18 14:17:55  gareth
 * Fix to bug #13438. When you eant a vector that calls delete[] on its members you should use RefArrayVectorOf.
 *
 * Revision 1.2  2002/11/04 14:53:27  tng
 * C++ Namespace Support.
 *
 * Revision 1.1.1.1  2002/02/01 22:22:40  peiyongz
 * sane_include
 *
 * Revision 1.10  2001/10/10 14:18:26  peiyongz
 * no message
 *
 * Revision 1.9  2001/10/09 20:53:58  peiyongz
 * init(): take 1 arg.
 *
 * Revision 1.8  2001/10/02 18:59:29  peiyongz
 * Invalid_Facet_Tag to display the tag name
 *
 * Revision 1.7  2001/09/24 15:33:15  peiyongz
 * DTV Reorganization: virtual methods moved to *.cpp
 *
 * Revision 1.6  2001/09/19 18:49:17  peiyongz
 * DTV reorganization: move inline to class declaration to avoid inline
 * function interdependency.
 *
 * Revision 1.5  2001/09/18 20:38:03  peiyongz
 * DTV reorganization: inherit from AbstractStringValidator.
 *
 * Revision 1.4  2001/08/21 18:42:53  peiyongz
 * Bugzilla# 2816: cleanUp() declared with external linkage and called
 *                          before defined as inline
 *
 * Revision 1.3  2001/08/14 22:11:56  peiyongz
 * new exception message added
 *
 * Revision 1.2  2001/08/10 16:21:19  peiyongz
 * use XMLUri instead of XMLURL
 *
 * Revision 1.1  2001/08/01 18:49:16  peiyongz
 * AnyRUIDatatypeValidator
 *
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/validators/datatype/AnyURIDatatypeValidator.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

//
//http://www.template.com
//
static const XMLCh BASE_URI[] =
{
    chLatin_h, chLatin_t, chLatin_t, chLatin_p,
    chColon, chForwardSlash, chForwardSlash,
    chLatin_w, chLatin_w, chLatin_w, chPeriod,
    chLatin_t, chLatin_e, chLatin_m, chLatin_p, chLatin_l,
    chLatin_a, chLatin_t, chLatin_e, chPeriod,
    chLatin_c, chLatin_o, chLatin_m, chNull
};

// ---------------------------------------------------------------------------
//  Constructors and Destructor
// ---------------------------------------------------------------------------
AnyURIDatatypeValidator::AnyURIDatatypeValidator(MemoryManager* const manager)
:AbstractStringValidator(0, 0, 0, DatatypeValidator::AnyURI, manager)
,fTempURI(0)
{}

AnyURIDatatypeValidator::~AnyURIDatatypeValidator()
{
    cleanUp();
}

AnyURIDatatypeValidator::AnyURIDatatypeValidator(
                          DatatypeValidator*            const baseValidator
                        , RefHashTableOf<KVStringPair>* const facets
                        , RefArrayVectorOf<XMLCh>*           const enums
                        , const int                           finalSet
                        , MemoryManager* const manager)
:AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::AnyURI, manager)
,fTempURI(0)
{
    try
    {
        init(enums);
    }
    catch (...)
    {
        cleanUp();
        throw;
    }
}

DatatypeValidator* AnyURIDatatypeValidator::newInstance(
                                      RefHashTableOf<KVStringPair>* const facets
                                    , RefArrayVectorOf<XMLCh>*           const enums
                                    , const int                           finalSet
                                    , MemoryManager* const manager)
{
    return (DatatypeValidator*) new AnyURIDatatypeValidator(this, facets, enums, finalSet, manager);
}

// ---------------------------------------------------------------------------
//  Utilities
// ---------------------------------------------------------------------------

void AnyURIDatatypeValidator::assignAdditionalFacet( const XMLCh* const key
                                                   , const XMLCh* const)
{
    ThrowXML1(InvalidDatatypeFacetException
            , XMLExcepts::FACET_Invalid_Tag
            , key);
}

void AnyURIDatatypeValidator::inheritAdditionalFacet()
{}

void AnyURIDatatypeValidator::checkAdditionalFacetConstraints() const
{}

void AnyURIDatatypeValidator::checkAdditionalFacet(const XMLCh* const) const
{}

int AnyURIDatatypeValidator::getLength(const XMLCh* const content) const
{
    return XMLString::stringLen(content);
}

void AnyURIDatatypeValidator::checkValueSpace(const XMLCh* const content)
{

    // check 3.2.17.c0 must: URI (rfc 2396/2723)
    try
    {
        if (!fTempURI)
            fTempURI = new (fMemoryManager) XMLUri(BASE_URI, fMemoryManager);

        // Support for relative URLs
        // According to Java 1.1: URLs may also be specified with a
        // String and the URL object that it is related to.
        //
        if (XMLString::stringLen(content))
        {
            if (!XMLUri::isValidURI(fTempURI, content))
                ThrowXML1(InvalidDatatypeValueException
                    , XMLExcepts::VALUE_URI_Malformed
                    , content);
        }
    }
    catch (...)
    {
        ThrowXML1(InvalidDatatypeValueException
                , XMLExcepts::VALUE_URI_Malformed
                , content);
    }

}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(AnyURIDatatypeValidator)

void AnyURIDatatypeValidator::serialize(XSerializeEngine& serEng)
{
    AbstractStringValidator::serialize(serEng);

    //don't serialize fTempURI
}

XERCES_CPP_NAMESPACE_END

/**
  * End of file AnyURIDatatypeValidator.cpp
  */
<|endoftext|>


<commit_before>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <string>

#include "tensorflow/lite/tools/delegates/delegate_provider.h"
#include "tensorflow/lite/tools/evaluation/utils.h"
#if defined(__APPLE__)
#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
// Only enable metal delegate when using a real iPhone device.
#define REAL_IPHONE_DEVICE
#include "tensorflow/lite/experimental/delegates/coreml/coreml_delegate.h"
#endif
#endif

namespace tflite {
namespace tools {

class CoreMlDelegateProvider : public DelegateProvider {
 public:
  CoreMlDelegateProvider() {
#if defined(REAL_IPHONE_DEVICE)
    default_params_.AddParam("use_coreml", ToolParam::Create<bool>(true));
    default_params_.AddParam("coreml_version", ToolParam::Create<int>(0));
#endif
  }
  std::vector<Flag> CreateFlags(ToolParams* params) const final;

  void LogParams(const ToolParams& params) const final;

  TfLiteDelegatePtr CreateTfLiteDelegate(const ToolParams& params) const final;

  std::string GetName() const final { return "COREML"; }
};
REGISTER_DELEGATE_PROVIDER(CoreMlDelegateProvider);

std::vector<Flag> CoreMlDelegateProvider::CreateFlags(
    ToolParams* params) const {
#if defined(REAL_IPHONE_DEVICE)
  std::vector<Flag> flags = {
      CreateFlag<bool>("use_coreml", params, "use Core ML"),
      CreateFlag<int>("coreml_version", params,
                      "Target Core ML version for model conversion. "
                      "The default value is 0 and it means using the newest "
                      "version that's available on the device."),
  };
  return flags;
#else
  return {};
#endif
}

void CoreMlDelegateProvider::LogParams(const ToolParams& params) const {
#if defined(REAL_IPHONE_DEVICE)
  TFLITE_LOG(INFO) << "Use Core ML : [" << params.Get<bool>("use_coreml")
                   << "]";
#endif
}

TfLiteDelegatePtr CoreMlDelegateProvider::CreateTfLiteDelegate(
    const ToolParams& params) const {
  TfLiteDelegatePtr delegate(nullptr, [](TfLiteDelegate*) {});

#if defined(REAL_IPHONE_DEVICE)
  if (params.Get<bool>("use_coreml")) {
    TfLiteCoreMlDelegateOptions coreml_opts = {
        .enabled_devices = TfLiteCoreMlDelegateAllDevices};
    coreml_opts.coreml_version = params.Get<int>("coreml_version");
    coreml_opts.max_delegated_partitions =
        params.Get<int>("max_delegated_partitions");
    coreml_opts.min_nodes_per_partition =
        params.Get<int>("min_nodes_per_partition");
    delegate = TfLiteDelegatePtr(TfLiteCoreMlDelegateCreate(&coreml_opts),
                                 &TfLiteCoreMlDelegateDelete);
    if (!delegate) {
      TFLITE_LOG(WARN)
          << "CoreML acceleration is unsupported on this platform.";
    }
  }
#endif

  return delegate;
}

}  // namespace tools
}  // namespace tflite
<commit_msg>Change the default value of 'use_coreml' parameter to false<commit_after>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <string>

#include "tensorflow/lite/tools/delegates/delegate_provider.h"
#include "tensorflow/lite/tools/evaluation/utils.h"
#if defined(__APPLE__)
#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
// Only enable metal delegate when using a real iPhone device.
#define REAL_IPHONE_DEVICE
#include "tensorflow/lite/experimental/delegates/coreml/coreml_delegate.h"
#endif
#endif

namespace tflite {
namespace tools {

class CoreMlDelegateProvider : public DelegateProvider {
 public:
  CoreMlDelegateProvider() {
#if defined(REAL_IPHONE_DEVICE)
    default_params_.AddParam("use_coreml", ToolParam::Create<bool>(false));
    default_params_.AddParam("coreml_version", ToolParam::Create<int>(0));
#endif
  }
  std::vector<Flag> CreateFlags(ToolParams* params) const final;

  void LogParams(const ToolParams& params) const final;

  TfLiteDelegatePtr CreateTfLiteDelegate(const ToolParams& params) const final;

  std::string GetName() const final { return "COREML"; }
};
REGISTER_DELEGATE_PROVIDER(CoreMlDelegateProvider);

std::vector<Flag> CoreMlDelegateProvider::CreateFlags(
    ToolParams* params) const {
#if defined(REAL_IPHONE_DEVICE)
  std::vector<Flag> flags = {
      CreateFlag<bool>("use_coreml", params, "use Core ML"),
      CreateFlag<int>("coreml_version", params,
                      "Target Core ML version for model conversion. "
                      "The default value is 0 and it means using the newest "
                      "version that's available on the device."),
  };
  return flags;
#else
  return {};
#endif
}

void CoreMlDelegateProvider::LogParams(const ToolParams& params) const {
#if defined(REAL_IPHONE_DEVICE)
  TFLITE_LOG(INFO) << "Use Core ML : [" << params.Get<bool>("use_coreml")
                   << "]";
#endif
}

TfLiteDelegatePtr CoreMlDelegateProvider::CreateTfLiteDelegate(
    const ToolParams& params) const {
  TfLiteDelegatePtr delegate(nullptr, [](TfLiteDelegate*) {});

#if defined(REAL_IPHONE_DEVICE)
  if (params.Get<bool>("use_coreml")) {
    TfLiteCoreMlDelegateOptions coreml_opts = {
        .enabled_devices = TfLiteCoreMlDelegateAllDevices};
    coreml_opts.coreml_version = params.Get<int>("coreml_version");
    coreml_opts.max_delegated_partitions =
        params.Get<int>("max_delegated_partitions");
    coreml_opts.min_nodes_per_partition =
        params.Get<int>("min_nodes_per_partition");
    delegate = TfLiteDelegatePtr(TfLiteCoreMlDelegateCreate(&coreml_opts),
                                 &TfLiteCoreMlDelegateDelete);
    if (!delegate) {
      TFLITE_LOG(WARN)
          << "CoreML acceleration is unsupported on this platform.";
    }
  }
#endif

  return delegate;
}

}  // namespace tools
}  // namespace tflite
<|endoftext|>


<commit_before>#include <string>
#include <cstring>
#include <vector>
#include "math3d/math3d.h"

#include "pbge/pbge.h"

#include "Ellipsoids.h"

Ellipsoids::Ellipsoids(pbge::GraphicAPI * _gfx, int total_ellipsoids) {
    std::vector<pbge::Model*> _models;
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 10, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 7, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 5, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 4, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 3, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 2, _gfx));
    std::vector<float> distances;
    distances.push_back(10.0f);
    distances.push_back(20.0f);
    distances.push_back(35.0f);
    distances.push_back(60.0f);
    distances.push_back(100.0f);
    this->models = new LODModels(_models, distances);
    this->gfx = _gfx;
    this->tex = gfx->getFactory()->createTextureBuffer(total_ellipsoids * sizeof(math3d::matrix44));
    this->added_ellipsoids = 0;
    this->render_pass_program = NULL;
    this->depth_pass_program = NULL;
    this->peeling_program = NULL;
    this->transformation_shader = NULL;
}

PeelingAwareCollection * Ellipsoids::createEllipsoids(unsigned number_of_ellipsoids, math3d::matrix44 * transforms, BoundingBox box) {
    void * texData = tex->getBuffer()->map(pbge::Buffer::WRITE_ONLY);
    memcpy((unsigned char *)texData + this->added_ellipsoids * sizeof(math3d::matrix44), transforms, number_of_ellipsoids * sizeof(math3d::matrix44));
    tex->getBuffer()->unmap();
    texData = NULL;
    tex->setInternalFormat(pbge::Texture::FLOAT, pbge::Texture::RGBA);
    PeelingAwareCollection * ellipsoids = new PeelingAwareCollection(models, get_peeling_program());
    ellipsoids->setNumberOfInstances(number_of_ellipsoids);

    pbge::UniformBufferSampler * uniform = ellipsoids->getUniformSet()->getBufferSampler("transforms");
    uniform->setValue(tex);
    ellipsoids->setTransforms(transforms);

    pbge::UniformFloat * base_instance = ellipsoids->getUniformSet()->getFloat("base_instance");
    base_instance->setValue((float)this->added_ellipsoids);
    this->added_ellipsoids += number_of_ellipsoids;

	ellipsoids->setRenderPassProgram(get_render_pass_program());
    ellipsoids->setDepthPassProgram(get_depth_pass_program());
    ellipsoids->setBoundingBox(box);
    return ellipsoids;
}

pbge::Shader * Ellipsoids::get_transformation_shader() {
    if(this->transformation_shader == NULL) {
        this->transformation_shader = gfx->getFactory()->createShaderFromString(
            "#version 150\n"
		    "uniform samplerBuffer transforms;\n"
            "uniform float base_instance;\n"
            "uniform float scale;\n"
            "uniform mat4 pbge_ModelViewMatrix;\n"
            "uniform float alpha_index;\n"
            "in  vec4 pbge_Vertex;\n"
            "void calc_transformations(out vec4 view_position, out vec3 view_normal, out vec4 color, out mat4 view_transform) {\n"
            "   int index = (int(base_instance) + gl_InstanceID) * 4;\n"
            "   vec4 vertex = vec4(pbge_Vertex.xyz * scale, 1.0);\n"
		    "   vec4 col1 = texelFetch(transforms, index);\n"
		    "   vec4 col2 = texelFetch(transforms, index + 1);\n"
		    "   vec4 col3 = texelFetch(transforms, index + 2);\n"
		    "   vec4 col4 = texelFetch(transforms, index + 3);\n"
		    "   color = vec4(col1.w,col2.w,col3.w,col4.w);\n"
            "   color = vec4(1,1,1,color[int(alpha_index)]);\n"
            "   col1 = vec4(col1.xyz, 0);\n"
		    "   col2 = vec4(col2.xyz, 0);\n"
		    "   col3 = vec4(col3.xyz, 0);\n"
		    "   col4 = vec4(col4.xyz, 1);\n"
		    "   mat4 transformation = mat4(col1, col2, col3, col4);\n"
		    "   view_transform = pbge_ModelViewMatrix * transformation;\n"
		    "   vec4 _normal = inverse(transpose(view_transform)) * pbge_Vertex;\n"
		    "   view_normal = normalize(_normal.xyz);\n"
		    "   view_position = view_transform * vertex;\n"
            "}",
            pbge::Shader::VERTEX_SHADER);
    }
    return this->transformation_shader;
}

pbge::GPUProgram * Ellipsoids::get_render_pass_program() {
    if(this->render_pass_program == NULL) {
        pbge::Shader * vertex_shader = gfx->getFactory()->createShaderFromString(
            "#version 150\n"
            "uniform mat4 pbge_ProjectionMatrix;\n"
            "out vec4 position;\n"
		    "out vec3 normal;\n"
		    "out vec4 lightPosition;\n"
		    "void calc_transformations(out vec4 view_position, out vec3 view_normal, out vec4 color, out mat4 view_tranform);\n"
            "void main() {\n"
		    "   mat4 view_transform;\n"
            "   const vec4 light_position = vec4(16,16,16,1);\n"
            "   calc_transformations(position, normal, gl_FrontColor, view_transform);\n"
            "   lightPosition = view_transform * light_position;\n"
		    "   gl_Position = pbge_ProjectionMatrix * position;\n"
		    "}",
            pbge::Shader::VERTEX_SHADER);
        pbge::Shader * frag_shader = gfx->getFactory()->createShaderFromString(
            "uniform float min_alpha;\n"
            "uniform float max_alpha;\n"
            "uniform vec4 min_color;\n"
            "uniform vec4 max_color;\n"
            "in vec4 position;\n"
		    "in vec3 normal;\n"
		    "in vec4 lightPosition;\n"
		    "void main() {\n"
            "   float alpha = gl_Color.a;\n"
            "   if(alpha <= min_alpha - 0.005) discard;\n"
            "   if(alpha >= max_alpha + 0.005) discard;\n"
            "   float rampIndex = (alpha - min_alpha) / max(max_alpha - min_alpha - 0.6,0.1);"
            "   vec4 diffuseColor = mix(min_color, max_color, rampIndex);\n"
		    "   vec4 lightDiffuseColor = vec4(1.0,1.0,1,1);\n"
		    "   vec3 lightDir = normalize((lightPosition - position).xyz);\n"
		    "   float intensity = max(0.0, dot(lightDir, normal));\n"
		    "   gl_FragData[0] = vec4(diffuseColor.rgb * lightDiffuseColor.rgb * intensity + 0.3, alpha);\n"
            "}",
            pbge::Shader::FRAGMENT_SHADER);
        std::vector<pbge::Shader *> vertex_shaders;
        std::vector<pbge::Shader *> fragment_shaders;

        vertex_shaders.push_back(vertex_shader);
        vertex_shaders.push_back(get_transformation_shader());
        fragment_shaders.push_back(frag_shader);
        this->render_pass_program = gfx->getFactory()->createProgram(
            vertex_shaders,
            fragment_shaders
            );
    }
    return this->render_pass_program;
}

pbge::GPUProgram * Ellipsoids::get_depth_pass_program() {
    if(this->depth_pass_program == NULL) {
        pbge::Shader * vertex_shader = gfx->getFactory()->createShaderFromString(
            "#version 150\n"
            "uniform mat4 pbge_ProjectionMatrix;\n"
            "out vec4 position;\n"
		    "out vec3 normal;\n"
		    "out vec4 lightPosition;\n"
		    "void calc_transformations(out vec4 view_position, out vec3 view_normal, out vec4 color, out mat4 view_tranform);\n"
            "void main() {\n"
		    "   mat4 view_transform;\n"
            "   calc_transformations(position, normal, gl_FrontColor, view_transform);\n"
            "   gl_Position = pbge_ProjectionMatrix * position;\n"
		    "}",
            pbge::Shader::VERTEX_SHADER);
        pbge::Shader * frag_shader = gfx->getFactory()->createShaderFromString(
            "",
            pbge::Shader::FRAGMENT_SHADER);
        std::vector<pbge::Shader *> vertex_shaders;
        std::vector<pbge::Shader *> fragment_shaders;

        vertex_shaders.push_back(vertex_shader);
        vertex_shaders.push_back(get_transformation_shader());
        fragment_shaders.push_back(frag_shader);
        this->depth_pass_program = gfx->getFactory()->createProgram(
            vertex_shaders,
            fragment_shaders
            );
    }
    return this->depth_pass_program;
}

pbge::GPUProgram * Ellipsoids::get_peeling_program() {
    if(this->peeling_program == NULL) {
        pbge::Shader * vertex_shader = gfx->getFactory()->createShaderFromString(
            "#version 150\n"
		    "uniform mat4 pbge_ProjectionMatrix;\n"
		    "out vec4 position;\n"
            "out vec4 nposition;\n"
		    "out vec3 normal;\n"
		    "out vec4 lightPosition;\n"
            "void calc_transformations(out vec4 view_position, out vec3 view_normal, out vec4 color, out mat4 view_tranform);\n"
            "void main() {\n"
            "   mat4 view_transform;\n"
            "   calc_transformations(position, normal, gl_FrontColor, view_transform);\n"
		    "   const vec4 light_position = vec4(16,16,16,1);\n"
            "   lightPosition = view_transform * light_position;\n"
            "   nposition = pbge_ProjectionMatrix * position;\n"
		    "   gl_Position = nposition;\n"
		    "}",
            pbge::Shader::VERTEX_SHADER);
        pbge::Shader * frag_shader = gfx->getFactory()->createShaderFromString(
            "in vec4 position;\n"
		    "in vec3 normal;\n"
		    "in vec4 lightPosition;\n"
            "in vec4 nposition;\n"
            "uniform sampler2D depth;\n"
            "uniform float min_alpha;\n"
            "uniform float max_alpha;\n"
            "uniform vec4 min_color;\n"
            "uniform vec4 max_color;\n"
		    "void main() {\n"
            // nposition is in ndc so we need to do the perspective division to transform the position
            // to the range -1 to 1.
            "   vec2 p = 0.5 * (nposition.xy / nposition.w) + 0.5;\n"
            "   float alpha = gl_Color.a;\n"
            // depth + offset to avoid z-fighting
            "   if(gl_FragCoord.z <= (texture2D(depth,p.xy)).r + 0.0001) discard;\n"
            "   if(normal.z >= 0) discard;\n"
            "   if(alpha <= min_alpha - 0.005) discard;\n"
            "   if(alpha >= max_alpha + 0.005) discard;\n"
            "   float rampIndex = (alpha - min_alpha) / max(max_alpha - min_alpha - 0.6,0.1);"
            "   vec4 diffuseColor = mix(min_color, max_color, rampIndex);\n"
            "   vec4 lightDiffuseColor = vec4(1.0,1.0,1,1);\n"
		    "   vec3 lightDir = normalize((lightPosition - position).xyz);\n"
		    "   float intensity = max(0.0, dot(lightDir, normal));\n"
		    "   gl_FragData[0] = vec4(diffuseColor.rgb * lightDiffuseColor.rgb * intensity + 0.2, alpha);\n"
            "}",
            pbge::Shader::FRAGMENT_SHADER);
        std::vector<pbge::Shader *> vertex_shaders;
        std::vector<pbge::Shader *> fragment_shaders;

        vertex_shaders.push_back(vertex_shader);
        vertex_shaders.push_back(get_transformation_shader());
        fragment_shaders.push_back(frag_shader);
        this->peeling_program = gfx->getFactory()->createProgram(
            vertex_shaders,
            fragment_shaders
            );
    }
    return this->peeling_program;
}<commit_msg>Using more saturated colors on glyphs<commit_after>#include <string>
#include <cstring>
#include <vector>
#include "math3d/math3d.h"

#include "pbge/pbge.h"

#include "Ellipsoids.h"

Ellipsoids::Ellipsoids(pbge::GraphicAPI * _gfx, int total_ellipsoids) {
    std::vector<pbge::Model*> _models;
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 10, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 7, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 5, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 4, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 3, _gfx));
    _models.push_back(pbge::Geometrics::createSphere(1.0f, 2, _gfx));
    std::vector<float> distances;
    distances.push_back(10.0f);
    distances.push_back(20.0f);
    distances.push_back(35.0f);
    distances.push_back(60.0f);
    distances.push_back(100.0f);
    this->models = new LODModels(_models, distances);
    this->gfx = _gfx;
    this->tex = gfx->getFactory()->createTextureBuffer(total_ellipsoids * sizeof(math3d::matrix44));
    this->added_ellipsoids = 0;
    this->render_pass_program = NULL;
    this->depth_pass_program = NULL;
    this->peeling_program = NULL;
    this->transformation_shader = NULL;
}

PeelingAwareCollection * Ellipsoids::createEllipsoids(unsigned number_of_ellipsoids, math3d::matrix44 * transforms, BoundingBox box) {
    void * texData = tex->getBuffer()->map(pbge::Buffer::WRITE_ONLY);
    memcpy((unsigned char *)texData + this->added_ellipsoids * sizeof(math3d::matrix44), transforms, number_of_ellipsoids * sizeof(math3d::matrix44));
    tex->getBuffer()->unmap();
    texData = NULL;
    tex->setInternalFormat(pbge::Texture::FLOAT, pbge::Texture::RGBA);
    PeelingAwareCollection * ellipsoids = new PeelingAwareCollection(models, get_peeling_program());
    ellipsoids->setNumberOfInstances(number_of_ellipsoids);

    pbge::UniformBufferSampler * uniform = ellipsoids->getUniformSet()->getBufferSampler("transforms");
    uniform->setValue(tex);
    ellipsoids->setTransforms(transforms);

    pbge::UniformFloat * base_instance = ellipsoids->getUniformSet()->getFloat("base_instance");
    base_instance->setValue((float)this->added_ellipsoids);
    this->added_ellipsoids += number_of_ellipsoids;

	ellipsoids->setRenderPassProgram(get_render_pass_program());
    ellipsoids->setDepthPassProgram(get_depth_pass_program());
    ellipsoids->setBoundingBox(box);
    return ellipsoids;
}

pbge::Shader * Ellipsoids::get_transformation_shader() {
    if(this->transformation_shader == NULL) {
        this->transformation_shader = gfx->getFactory()->createShaderFromString(
            "#version 150\n"
		    "uniform samplerBuffer transforms;\n"
            "uniform float base_instance;\n"
            "uniform float scale;\n"
            "uniform mat4 pbge_ModelViewMatrix;\n"
            "uniform float alpha_index;\n"
            "in  vec4 pbge_Vertex;\n"
            "void calc_transformations(out vec4 view_position, out vec3 view_normal, out vec4 color, out mat4 view_transform) {\n"
            "   int index = (int(base_instance) + gl_InstanceID) * 4;\n"
            "   vec4 vertex = vec4(pbge_Vertex.xyz * scale, 1.0);\n"
		    "   vec4 col1 = texelFetch(transforms, index);\n"
		    "   vec4 col2 = texelFetch(transforms, index + 1);\n"
		    "   vec4 col3 = texelFetch(transforms, index + 2);\n"
		    "   vec4 col4 = texelFetch(transforms, index + 3);\n"
		    "   color = vec4(col1.w,col2.w,col3.w,col4.w);\n"
            "   color = vec4(1,1,1,color[int(alpha_index)]);\n"
            "   col1 = vec4(col1.xyz, 0);\n"
		    "   col2 = vec4(col2.xyz, 0);\n"
		    "   col3 = vec4(col3.xyz, 0);\n"
		    "   col4 = vec4(col4.xyz, 1);\n"
		    "   mat4 transformation = mat4(col1, col2, col3, col4);\n"
		    "   view_transform = pbge_ModelViewMatrix * transformation;\n"
		    "   vec4 _normal = inverse(transpose(view_transform)) * pbge_Vertex;\n"
		    "   view_normal = normalize(_normal.xyz);\n"
		    "   view_position = view_transform * vertex;\n"
            "}",
            pbge::Shader::VERTEX_SHADER);
    }
    return this->transformation_shader;
}

pbge::GPUProgram * Ellipsoids::get_render_pass_program() {
    if(this->render_pass_program == NULL) {
        pbge::Shader * vertex_shader = gfx->getFactory()->createShaderFromString(
            "#version 150\n"
            "uniform mat4 pbge_ProjectionMatrix;\n"
            "out vec4 position;\n"
		    "out vec3 normal;\n"
		    "out vec4 lightPosition;\n"
		    "void calc_transformations(out vec4 view_position, out vec3 view_normal, out vec4 color, out mat4 view_tranform);\n"
            "void main() {\n"
		    "   mat4 view_transform;\n"
            "   const vec4 light_position = vec4(16,16,16,1);\n"
            "   calc_transformations(position, normal, gl_FrontColor, view_transform);\n"
            "   lightPosition = view_transform * light_position;\n"
		    "   gl_Position = pbge_ProjectionMatrix * position;\n"
		    "}",
            pbge::Shader::VERTEX_SHADER);
        pbge::Shader * frag_shader = gfx->getFactory()->createShaderFromString(
            "uniform float min_alpha;\n"
            "uniform float max_alpha;\n"
            "uniform vec4 min_color;\n"
            "uniform vec4 max_color;\n"
            "in vec4 position;\n"
		    "in vec3 normal;\n"
		    "in vec4 lightPosition;\n"
		    "void main() {\n"
            "   float alpha = gl_Color.a;\n"
            "   if(alpha <= min_alpha - 0.005) discard;\n"
            "   if(alpha >= max_alpha + 0.005) discard;\n"
            "   float rampIndex = (alpha - min_alpha) / max(max_alpha - min_alpha - 0.6,0.1);"
            "   vec4 diffuseColor = mix(min_color, max_color, rampIndex);\n"
            "   vec4 lightDiffuseColor = vec4(1.0,1.0,1,1);\n"
		    "   vec3 lightDir = normalize((lightPosition - position).xyz);\n"
		    "   float intensity = max(0.0, dot(lightDir, normal));\n"
		    "   gl_FragData[0] = vec4(diffuseColor.rgb * lightDiffuseColor.rgb * intensity, alpha);\n"
            "}",
            pbge::Shader::FRAGMENT_SHADER);
        std::vector<pbge::Shader *> vertex_shaders;
        std::vector<pbge::Shader *> fragment_shaders;

        vertex_shaders.push_back(vertex_shader);
        vertex_shaders.push_back(get_transformation_shader());
        fragment_shaders.push_back(frag_shader);
        this->render_pass_program = gfx->getFactory()->createProgram(
            vertex_shaders,
            fragment_shaders
            );
    }
    return this->render_pass_program;
}

pbge::GPUProgram * Ellipsoids::get_depth_pass_program() {
    if(this->depth_pass_program == NULL) {
        pbge::Shader * vertex_shader = gfx->getFactory()->createShaderFromString(
            "#version 150\n"
            "uniform mat4 pbge_ProjectionMatrix;\n"
            "out vec4 position;\n"
		    "out vec3 normal;\n"
		    "out vec4 lightPosition;\n"
		    "void calc_transformations(out vec4 view_position, out vec3 view_normal, out vec4 color, out mat4 view_tranform);\n"
            "void main() {\n"
		    "   mat4 view_transform;\n"
            "   calc_transformations(position, normal, gl_FrontColor, view_transform);\n"
            "   gl_Position = pbge_ProjectionMatrix * position;\n"
		    "}",
            pbge::Shader::VERTEX_SHADER);
        pbge::Shader * frag_shader = gfx->getFactory()->createShaderFromString(
            "",
            pbge::Shader::FRAGMENT_SHADER);
        std::vector<pbge::Shader *> vertex_shaders;
        std::vector<pbge::Shader *> fragment_shaders;

        vertex_shaders.push_back(vertex_shader);
        vertex_shaders.push_back(get_transformation_shader());
        fragment_shaders.push_back(frag_shader);
        this->depth_pass_program = gfx->getFactory()->createProgram(
            vertex_shaders,
            fragment_shaders
            );
    }
    return this->depth_pass_program;
}

pbge::GPUProgram * Ellipsoids::get_peeling_program() {
    if(this->peeling_program == NULL) {
        pbge::Shader * vertex_shader = gfx->getFactory()->createShaderFromString(
            "#version 150\n"
		    "uniform mat4 pbge_ProjectionMatrix;\n"
		    "out vec4 position;\n"
            "out vec4 nposition;\n"
		    "out vec3 normal;\n"
		    "out vec4 lightPosition;\n"
            "void calc_transformations(out vec4 view_position, out vec3 view_normal, out vec4 color, out mat4 view_tranform);\n"
            "void main() {\n"
            "   mat4 view_transform;\n"
            "   calc_transformations(position, normal, gl_FrontColor, view_transform);\n"
		    "   const vec4 light_position = vec4(16,16,16,1);\n"
            "   lightPosition = view_transform * light_position;\n"
            "   nposition = pbge_ProjectionMatrix * position;\n"
		    "   gl_Position = nposition;\n"
		    "}",
            pbge::Shader::VERTEX_SHADER);
        pbge::Shader * frag_shader = gfx->getFactory()->createShaderFromString(
            "in vec4 position;\n"
		    "in vec3 normal;\n"
		    "in vec4 lightPosition;\n"
            "in vec4 nposition;\n"
            "uniform sampler2D depth;\n"
            "uniform float min_alpha;\n"
            "uniform float max_alpha;\n"
            "uniform vec4 min_color;\n"
            "uniform vec4 max_color;\n"
		    "void main() {\n"
            // nposition is in ndc so we need to do the perspective division to transform the position
            // to the range -1 to 1.
            "   vec2 p = 0.5 * (nposition.xy / nposition.w) + 0.5;\n"
            "   float alpha = gl_Color.a;\n"
            // depth + offset to avoid z-fighting
            "   if(gl_FragCoord.z <= (texture2D(depth,p.xy)).r + 0.0001) discard;\n"
            "   if(normal.z >= 0) discard;\n"
            "   if(alpha <= min_alpha - 0.005) discard;\n"
            "   if(alpha >= max_alpha + 0.005) discard;\n"
            "   float rampIndex = (alpha - min_alpha) / max(max_alpha - min_alpha - 0.6,0.1);"
            "   vec4 diffuseColor = mix(min_color, max_color, rampIndex);\n"
            "   vec4 lightDiffuseColor = vec4(1.0,1.0,1,1);\n"
		    "   vec3 lightDir = normalize((lightPosition - position).xyz);\n"
		    "   float intensity = max(0.0, dot(lightDir, normal));\n"
		    "   gl_FragData[0] = vec4(diffuseColor.rgb * lightDiffuseColor.rgb * intensity, alpha);\n"
            "}",
            pbge::Shader::FRAGMENT_SHADER);
        std::vector<pbge::Shader *> vertex_shaders;
        std::vector<pbge::Shader *> fragment_shaders;

        vertex_shaders.push_back(vertex_shader);
        vertex_shaders.push_back(get_transformation_shader());
        fragment_shaders.push_back(frag_shader);
        this->peeling_program = gfx->getFactory()->createProgram(
            vertex_shaders,
            fragment_shaders
            );
    }
    return this->peeling_program;
}<|endoftext|>


<commit_before><commit_msg>branchless wrapAngle<commit_after><|endoftext|>