
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkData.h"
#include "SkDecodingImageGenerator.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkXfermode.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkTime.h"
#include "SkTypeface.h"

#include "SkStream.h"

static void make_image(SkBitmap* bm, SkColorType ct, int configIndex) {
    const int   width = 98;
    const int   height = 100;
    const SkImageInfo info = SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType);

    SkBitmap    device;
    device.allocN32Pixels(width, height);
    SkCanvas    canvas(device);
    SkPaint     paint;

    paint.setAntiAlias(true);
    canvas.drawColor(SK_ColorRED);
    paint.setColor(SK_ColorBLUE);
    canvas.drawCircle(SkIntToScalar(width)/2, SkIntToScalar(height)/2,
                      SkIntToScalar(width)/2, paint);

    switch (ct) {
        case kPMColor_SkColorType:
            bm->swap(device);
            break;
        case kRGB_565_SkColorType: {
            bm->allocPixels(info);
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    *bm->getAddr16(x, y) = SkPixel32ToPixel16(*device.getAddr32(x, y));
                }
            }
            break;
        }
        case kIndex_8_SkColorType: {
            SkPMColor colors[256];
            for (int i = 0; i < 256; i++) {
                if (configIndex & 1) {
                    colors[i] = SkPackARGB32(255-i, 0, 0, 255-i);
                } else {
                    colors[i] = SkPackARGB32(0xFF, i, 0, 255-i);
                }
            }
            SkColorTable* ctable = new SkColorTable(colors, 256);
            bm->allocPixels(info, NULL, ctable);
            ctable->unref();
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    *bm->getAddr8(x, y) = SkGetPackedR32(*device.getAddr32(x, y));
                }
            }
            break;
        }
        default:
            SkASSERT(0);
    }
}

// configs to build the original bitmap in. Can be at most these 3
static const SkColorType gColorTypes[] = {
    kPMColor_SkColorType,
    kRGB_565_SkColorType,
    kIndex_8_SkColorType,   // opaque
    kIndex_8_SkColorType    // alpha
};

static const char* const gConfigLabels[] = {
    "8888", "565", "Index8",  "Index8 alpha"
};

// types to encode into. Can be at most these 3. Must match up with gExt[]
static const SkImageEncoder::Type gTypes[] = {
    SkImageEncoder::kJPEG_Type,
    SkImageEncoder::kPNG_Type
};

// must match up with gTypes[]
static const char* const gExt[] = {
    ".jpg", ".png"
};

#include <sys/stat.h>

class EncodeView : public SampleView {
public:
    SkBitmap*        fBitmaps;
    SkAutoDataUnref* fEncodedPNGs;
    SkAutoDataUnref* fEncodedJPEGs;
    int              fBitmapCount;

    EncodeView() {
        fBitmapCount = SK_ARRAY_COUNT(gColorTypes);
        fBitmaps = new SkBitmap[fBitmapCount];
        fEncodedPNGs = new SkAutoDataUnref[fBitmapCount];
        fEncodedJPEGs = new SkAutoDataUnref[fBitmapCount];
        for (int i = 0; i < fBitmapCount; i++) {
            make_image(&fBitmaps[i], gColorTypes[i], i);

            for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) {
                SkAutoTDelete<SkImageEncoder> codec(
                    SkImageEncoder::Create(gTypes[j]));
                if (NULL == codec.get()) {
                    SkDebugf("[%s:%d] failed to encode %s%s\n",
                             __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
                    continue;
                }
                SkAutoDataUnref data(codec->encodeData(fBitmaps[i], 100));
                if (NULL == data.get()) {
                    SkDebugf("[%s:%d] failed to encode %s%s\n",
                             __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
                    continue;
                }
                if (SkImageEncoder::kJPEG_Type == gTypes[j]) {
                    fEncodedJPEGs[i].reset(data.detach());
                } else if (SkImageEncoder::kPNG_Type == gTypes[j]) {
                    fEncodedPNGs[i].reset(data.detach());
                }
            }
        }
        this->setBGColor(0xFFDDDDDD);
    }

    virtual ~EncodeView() {
        delete[] fBitmaps;
        delete[] fEncodedPNGs;
        delete[] fEncodedJPEGs;
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "ImageEncoder");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        if (fBitmapCount == 0) {
            return;
        }

        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setTextAlign(SkPaint::kCenter_Align);

        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));

        SkScalar x = 0, y = 0, maxX = 0;
        const int SPACER = 10;

        for (int i = 0; i < fBitmapCount; i++) {
            canvas->drawText(gConfigLabels[i], strlen(gConfigLabels[i]),
                             x + SkIntToScalar(fBitmaps[i].width()) / 2, 0,
                             paint);
            y = paint.getTextSize();

            canvas->drawBitmap(fBitmaps[i], x, y);

            SkScalar yy = y;
            for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) {
                yy += SkIntToScalar(fBitmaps[i].height() + 10);

                SkBitmap bm;
                SkData* encoded = NULL;
                if (SkImageEncoder::kJPEG_Type == gTypes[j]) {
                    encoded = fEncodedJPEGs[i].get();
                } else if (SkImageEncoder::kPNG_Type == gTypes[j]) {
                    encoded = fEncodedPNGs[i].get();
                }
                if (encoded) {
                    if (!SkInstallDiscardablePixelRef(
                            SkDecodingImageGenerator::Create(encoded,
                                SkDecodingImageGenerator::Options()),
                            &bm, NULL)) {
                    SkDebugf("[%s:%d] failed to decode %s%s\n",
                             __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
                    }
                    canvas->drawBitmap(bm, x, yy);
                }
            }

            x += SkIntToScalar(fBitmaps[i].width() + SPACER);
            if (x > maxX) {
                maxX = x;
            }
        }

        y = (paint.getTextSize() + SkIntToScalar(fBitmaps[0].height())) * 3 / 2;
        x = maxX + SkIntToScalar(10);
        paint.setTextAlign(SkPaint::kLeft_Align);

        for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) {
            canvas->drawText(gExt[j], strlen(gExt[j]), x, y, paint);
            y += SkIntToScalar(fBitmaps[0].height() + SPACER);
        }
    }

    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                              unsigned modi) {
        this->inval(NULL);
        return this->INHERITED::onFindClickHandler(x, y, modi);
    }

private:
    typedef SampleView INHERITED;
};

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

static SkView* MyFactory() { return new EncodeView; }
static SkViewRegister reg(MyFactory);
