
/*
 * Copyright 2010 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 "SkPDFImage.h"

#include "SkBitmap.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkPackBits.h"
#include "SkPDFCatalog.h"
#include "SkRect.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkUnPreMultiply.h"

namespace {

void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect,
                      SkStream** imageData, SkStream** alphaData) {
    SkMemoryStream* image = NULL;
    SkMemoryStream* alpha = NULL;
    bool hasAlpha = false;
    bool isTransparent = false;

    bitmap.lockPixels();
    switch (bitmap.getConfig()) {
        case SkBitmap::kIndex8_Config: {
            const int rowBytes = srcRect.width();
            image = new SkMemoryStream(rowBytes * srcRect.height());
            uint8_t* dst = (uint8_t*)image->getMemoryBase();
            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
                memcpy(dst, bitmap.getAddr8(srcRect.fLeft, y), rowBytes);
                dst += rowBytes;
            }
            break;
        }
        case SkBitmap::kRLE_Index8_Config: {
            const int rowBytes = srcRect.width();
            image = new SkMemoryStream(rowBytes * srcRect.height());
            uint8_t* dst = (uint8_t*)image->getMemoryBase();
            const SkBitmap::RLEPixels* rle =
                (const SkBitmap::RLEPixels*)bitmap.getPixels();
            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
                SkPackBits::Unpack8(dst, srcRect.fLeft, rowBytes,
                                    rle->packedAtY(y));
                dst += rowBytes;
            }
            break;
        }
        case SkBitmap::kARGB_4444_Config: {
            isTransparent = true;
            const int rowBytes = (srcRect.width() * 3 + 1) / 2;
            const int alphaRowBytes = (srcRect.width() + 1) / 2;
            image = new SkMemoryStream(rowBytes * srcRect.height());
            alpha = new SkMemoryStream(alphaRowBytes * srcRect.height());
            uint8_t* dst = (uint8_t*)image->getMemoryBase();
            uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase();
            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
                uint16_t* src = bitmap.getAddr16(0, y);
                int x;
                for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) {
                    dst[0] = (SkGetPackedR4444(src[x]) << 4) |
                        SkGetPackedG4444(src[x]);
                    dst[1] = (SkGetPackedB4444(src[x]) << 4) |
                        SkGetPackedR4444(src[x + 1]);
                    dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) |
                        SkGetPackedB4444(src[x + 1]);
                    dst += 3;
                    alphaDst[0] = (SkGetPackedA4444(src[x]) << 4) |
                        SkGetPackedA4444(src[x + 1]);
                    if (alphaDst[0] != 0xFF) {
                        hasAlpha = true;
                    }
                    if (alphaDst[0]) {
                        isTransparent = false;
                    }
                    alphaDst++;
                }
                if (srcRect.width() & 1) {
                    dst[0] = (SkGetPackedR4444(src[x]) << 4) |
                        SkGetPackedG4444(src[x]);
                    dst[1] = (SkGetPackedB4444(src[x]) << 4);
                    dst += 2;
                    alphaDst[0] = (SkGetPackedA4444(src[x]) << 4);
                    if (alphaDst[0] != 0xF0) {
                        hasAlpha = true;
                    }
                    if (alphaDst[0] & 0xF0) {
                        isTransparent = false;
                    }
                    alphaDst++;
                }
            }
            break;
        }
        case SkBitmap::kRGB_565_Config: {
            const int rowBytes = srcRect.width() * 3;
            image = new SkMemoryStream(rowBytes * srcRect.height());
            uint8_t* dst = (uint8_t*)image->getMemoryBase();
            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
                uint16_t* src = bitmap.getAddr16(0, y);
                for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
                    dst[0] = SkGetPackedR16(src[x]);
                    dst[1] = SkGetPackedG16(src[x]);
                    dst[2] = SkGetPackedB16(src[x]);
                    dst += 3;
                }
            }
            break;
        }
        case SkBitmap::kARGB_8888_Config: {
            isTransparent = true;
            const int rowBytes = srcRect.width() * 3;
            image = new SkMemoryStream(rowBytes * srcRect.height());
            alpha = new SkMemoryStream(srcRect.width() * srcRect.height());
            uint8_t* dst = (uint8_t*)image->getMemoryBase();
            uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase();
            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
                uint32_t* src = bitmap.getAddr32(0, y);
                for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
                    dst[0] = SkGetPackedR32(src[x]);
                    dst[1] = SkGetPackedG32(src[x]);
                    dst[2] = SkGetPackedB32(src[x]);
                    dst += 3;
                    alphaDst[0] = SkGetPackedA32(src[x]);
                    if (alphaDst[0] != 0xFF) {
                        hasAlpha = true;
                    }
                    if (alphaDst[0]) {
                        isTransparent = false;
                    }
                    alphaDst++;
                }
            }
            break;
        }
        case SkBitmap::kA1_Config: {
            isTransparent = true;
            image = new SkMemoryStream(1);
            ((uint8_t*)image->getMemoryBase())[0] = 0;

            const int alphaRowBytes = (srcRect.width() + 7) / 8;
            alpha = new SkMemoryStream(alphaRowBytes * srcRect.height());
            uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase();
            int offset1 = srcRect.fLeft % 8;
            int offset2 = 8 - offset1;
            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
                uint8_t* src = bitmap.getAddr1(0, y);
                // This may read up to one byte after src, but the potentially
                // invalid bits are never used for computation.
                for (int x = srcRect.fLeft; x < srcRect.fRight; x += 8)  {
                    if (offset1) {
                        alphaDst[0] = src[x / 8] << offset1 |
                            src[x / 8 + 1] >> offset2;
                    } else {
                        alphaDst[0] = src[x / 8];
                    }
                    if (x + 7 < srcRect.fRight && alphaDst[0] != 0xFF) {
                        hasAlpha = true;
                    }
                    if (x + 7 < srcRect.fRight && alphaDst[0]) {
                        isTransparent = false;
                    }
                    alphaDst++;
                }
                // Calculate the mask of bits we're interested in within the
                // last byte of alphaDst.
                // width mod 8  == 1 -> 0x80 ... width mod 8 == 7 -> 0xFE
                uint8_t mask = ~((1 << (8 - (srcRect.width() % 8))) - 1);
                if (srcRect.width() % 8 && (alphaDst[-1] & mask) != mask) {
                    hasAlpha = true;
                }
                if (srcRect.width() % 8 && (alphaDst[-1] & mask)) {
                    isTransparent = false;
                }
            }
            break;
        }
        case SkBitmap::kA8_Config: {
            isTransparent = true;
            image = new SkMemoryStream(1);
            ((uint8_t*)image->getMemoryBase())[0] = 0;

            const int alphaRowBytes = srcRect.width();
            alpha = new SkMemoryStream(alphaRowBytes * srcRect.height());
            uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase();
            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
                uint8_t* src = bitmap.getAddr8(0, y);
                for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
                    alphaDst[0] = src[x];
                    if (alphaDst[0] != 0xFF) {
                        hasAlpha = true;
                    }
                    if (alphaDst[0]) {
                        isTransparent = false;
                    }
                    alphaDst++;
                }
            }
            break;
        }
        default:
            SkASSERT(false);
    }
    bitmap.unlockPixels();

    if (isTransparent) {
        SkSafeUnref(image);
    } else {
        *imageData = image;
    }

    if (isTransparent || !hasAlpha) {
        SkSafeUnref(alpha);
    } else {
        *alphaData = alpha;
    }
}

SkPDFArray* makeIndexedColorSpace(SkColorTable* table) {
    SkPDFArray* result = new SkPDFArray();
    result->reserve(4);
    result->appendName("Indexed");
    result->appendName("DeviceRGB");
    result->appendInt(table->count() - 1);

    // Potentially, this could be represented in fewer bytes with a stream.
    // Max size as a string is 1.5k.
    SkString index;
    for (int i = 0; i < table->count(); i++) {
        char buf[3];
        SkColor color = SkUnPreMultiply::PMColorToColor((*table)[i]);
        buf[0] = SkGetPackedR32(color);
        buf[1] = SkGetPackedG32(color);
        buf[2] = SkGetPackedB32(color);
        index.append(buf, 3);
    }
    result->append(new SkPDFString(index))->unref();
    return result;
}

};  // namespace

// static
SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap,
                                    const SkIRect& srcRect,
                                    EncodeToDCTStream encoder) {
    if (bitmap.getConfig() == SkBitmap::kNo_Config) {
        return NULL;
    }

    SkStream* imageData = NULL;
    SkStream* alphaData = NULL;
    extractImageData(bitmap, srcRect, &imageData, &alphaData);
    SkAutoUnref unrefImageData(imageData);
    SkAutoUnref unrefAlphaData(alphaData);
    if (!imageData) {
        SkASSERT(!alphaData);
        return NULL;
    }

    SkPDFImage* image =
        SkNEW_ARGS(SkPDFImage, (imageData, bitmap, srcRect, false, encoder));

    if (alphaData != NULL) {
        // Don't try to use DCT compression with alpha because alpha is small
        // anyway and it could lead to artifacts.
        image->addSMask(SkNEW_ARGS(SkPDFImage, (alphaData, bitmap, srcRect, true, NULL)))->unref();
    }
    return image;
}

SkPDFImage::~SkPDFImage() {
    fResources.unrefAll();
}

SkPDFImage* SkPDFImage::addSMask(SkPDFImage* mask) {
    fResources.push(mask);
    mask->ref();
    insert("SMask", new SkPDFObjRef(mask))->unref();
    return mask;
}

void SkPDFImage::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
                              SkTSet<SkPDFObject*>* newResourceObjects) {
    GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects);
}

SkPDFImage::SkPDFImage(SkStream* imageData,
                       const SkBitmap& bitmap,
                       const SkIRect& srcRect,
                       bool doingAlpha,
                       EncodeToDCTStream encoder)
        : SkPDFImageStream(imageData, bitmap, srcRect, encoder) {
    SkBitmap::Config config = bitmap.getConfig();
    bool alphaOnly = (config == SkBitmap::kA1_Config ||
                      config == SkBitmap::kA8_Config);

    insertName("Type", "XObject");
    insertName("Subtype", "Image");

    if (!doingAlpha && alphaOnly) {
        // For alpha only images, we stretch a single pixel of black for
        // the color/shape part.
        SkAutoTUnref<SkPDFInt> one(new SkPDFInt(1));
        insert("Width", one.get());
        insert("Height", one.get());
    } else {
        insertInt("Width", srcRect.width());
        insertInt("Height", srcRect.height());
    }

    // if (!image mask) {
    if (doingAlpha || alphaOnly) {
        insertName("ColorSpace", "DeviceGray");
    } else if (config == SkBitmap::kIndex8_Config ||
        config == SkBitmap::kRLE_Index8_Config) {
        insert("ColorSpace",
               makeIndexedColorSpace(bitmap.getColorTable()))->unref();
    } else {
        insertName("ColorSpace", "DeviceRGB");
    }
    // }

    int bitsPerComp = 8;
    if (config == SkBitmap::kARGB_4444_Config) {
        bitsPerComp = 4;
    } else if (doingAlpha && config == SkBitmap::kA1_Config) {
        bitsPerComp = 1;
    }
    insertInt("BitsPerComponent", bitsPerComp);

    if (config == SkBitmap::kRGB_565_Config) {
        SkAutoTUnref<SkPDFInt> zeroVal(new SkPDFInt(0));
        SkAutoTUnref<SkPDFScalar> scale5Val(
                new SkPDFScalar(SkFloatToScalar(8.2258f)));  // 255/2^5-1
        SkAutoTUnref<SkPDFScalar> scale6Val(
                new SkPDFScalar(SkFloatToScalar(4.0476f)));  // 255/2^6-1
        SkAutoTUnref<SkPDFArray> decodeValue(new SkPDFArray());
        decodeValue->reserve(6);
        decodeValue->append(zeroVal.get());
        decodeValue->append(scale5Val.get());
        decodeValue->append(zeroVal.get());
        decodeValue->append(scale6Val.get());
        decodeValue->append(zeroVal.get());
        decodeValue->append(scale5Val.get());
        insert("Decode", decodeValue.get());
    }
}
