示例#1
0
static uint32_t get_argb8888_neighbor_avg_color(const SkBitmap& bitmap,
                                                int xOrig, int yOrig) {
    uint8_t count = 0;
    uint16_t r = 0;
    uint16_t g = 0;
    uint16_t b = 0;

    for (int y = yOrig - 1; y <= yOrig + 1; y++) {
        if (y < 0 || y >= bitmap.height()) {
            continue;
        }
        uint32_t* src = bitmap.getAddr32(0, y);
        for (int x = xOrig - 1; x <= xOrig + 1; x++) {
            if (x < 0 || x >= bitmap.width()) {
                continue;
            }
            if (SkGetPackedA32(src[x]) != SK_AlphaTRANSPARENT) {
                uint32_t color = remove_alpha_argb8888(src[x]);
                r += SkGetPackedR32(color);
                g += SkGetPackedG32(color);
                b += SkGetPackedB32(color);
                count++;
            }
        }
    }

    if (count == 0) {
        return SkPackARGB32NoCheck(SK_AlphaOPAQUE, 0, 0, 0);
    } else {
        return SkPackARGB32NoCheck(SK_AlphaOPAQUE,
                                   r / count, g / count, b / count);
    }
}
/*
 * Set an RLE pixel from R, G, B values
 */
void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes,
                                const SkImageInfo& dstInfo, uint32_t x,
                                uint32_t y, uint8_t red, uint8_t green,
                                uint8_t blue) {
    // Set the row
    int height = dstInfo.height();
    int row;
    if (SkBmpCodec::kBottomUp_RowOrder == this->rowOrder()) {
        row = height - y - 1;
    } else {
        row = y;
    }

    // Set the pixel based on destination color type
    switch (dstInfo.colorType()) {
        case kN32_SkColorType: {
            SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
                    row * (int) dstRowBytes);
            dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue);
            break;
        }
        case kRGB_565_SkColorType: {
            uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (int) dstRowBytes);
            dstRow[x] = SkPack888ToRGB16(red, green, blue);
            break;
        }
        default:
            // This case should not be reached.  We should catch an invalid
            // color type when we check that the conversion is possible.
            SkASSERT(false);
            break;
    }
}
示例#3
0
/**
 * Removes the alpha component of an ARGB color (including unpremultiply) while
 * keeping the output in the same format as the input.
 */
static uint32_t remove_alpha_argb8888(uint32_t pmColor) {
    SkColor color = SkUnPreMultiply::PMColorToColor(pmColor);
    return SkPackARGB32NoCheck(SK_AlphaOPAQUE,
                               SkColorGetR(color),
                               SkColorGetG(color),
                               SkColorGetB(color));
}
示例#4
0
/*
 * Set an RLE pixel from R, G, B values
 */
void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes,
                                const SkImageInfo& dstInfo, uint32_t x,
                                uint32_t y, uint8_t red, uint8_t green,
                                uint8_t blue) {
    if (is_coord_necessary(x, fSampleX, dstInfo.width())) {
        // Set the row
        uint32_t row = this->getDstRow(y, dstInfo.height());

        // Set the pixel based on destination color type
        const int dstX = get_dst_coord(x, fSampleX);
        switch (dstInfo.colorType()) {
            case kN32_SkColorType: {
                SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes);
                dstRow[dstX] = SkPackARGB32NoCheck(0xFF, red, green, blue);
                break;
            }
            case kRGB_565_SkColorType: {
                uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (int) dstRowBytes);
                dstRow[dstX] = SkPack888ToRGB16(red, green, blue);
                break;
            }
            default:
                // This case should not be reached.  We should catch an invalid
                // color type when we check that the conversion is possible.
                SkASSERT(false);
                break;
        }
    }
}
// Returns an unpremultiplied version of color. It will have the same ordering and size as an
// SkPMColor, but the alpha will not be premultiplied.
static SkPMColor unpremultiply_pmcolor(SkPMColor color) {
    U8CPU a = SkGetPackedA32(color);
    const SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(a);
    return SkPackARGB32NoCheck(a,
                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedR32(color)),
                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedG32(color)),
                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedB32(color)));
}
static SkPMColor unpremul_pm(SkPMColor c) {
    const U8CPU a = SkGetPackedA32(c);
    if (0 == a) {
        return 0;
    } else if (0xFF == a) {
        return c;
    }
    const unsigned scale = SkUnPreMultiply::GetScale(a);
    return SkPackARGB32NoCheck(a,
                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedR32(c)),
                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedG32(c)),
                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedB32(c)));
}
示例#7
0
static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_opaque(
        void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {

    // Use the masks to decode to the destination
    SkPMColor* dstPtr = (SkPMColor*) dstRow;
    for (int i = 0; i < 3*width; i += 3) {
        uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
        uint8_t red = masks->getRed(p);
        uint8_t green = masks->getGreen(p);
        uint8_t blue = masks->getBlue(p);
        dstPtr[i/3] = SkPackARGB32NoCheck(0xFF, red, green, blue);
    }
    return SkSwizzler::kOpaque_ResultAlpha;
}
示例#8
0
static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_opaque(
        void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {

    // Use the masks to decode to the destination
    uint16_t* srcPtr = (uint16_t*) srcRow;
    SkPMColor* dstPtr = (SkPMColor*) dstRow;
    for (int i = 0; i < width; i++) {
        uint16_t p = srcPtr[i];
        uint8_t red = masks->getRed(p);
        uint8_t green = masks->getGreen(p);
        uint8_t blue = masks->getBlue(p);
        dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
    }
    return SkSwizzler::kOpaque_ResultAlpha;
}
示例#9
0
static void FromColor_D4444_Raw(void* dst, const SkColor src[], int width,
                            int x, int y) {
    SkPMColor16* d = (SkPMColor16*)dst;

    DITHER_4444_SCAN(y);
    for (int stop = x + width; x < stop; x++) {
        SkColor c = *src++;

        // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied
        SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),
                                            SkColorGetG(c), SkColorGetB(c));
        *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));
//        *d++ = SkPixel32ToPixel4444(pmc);
    }
}
示例#10
0
static void FromColor_D32_Raw(void* dst, const SkColor src[], int width,
                          int, int) {
    // SkColor's ordering may be different from SkPMColor
    if (SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER) {
        memcpy(dst, src, width * sizeof(SkColor));
        return;
    }

    // order isn't same, repack each pixel manually
    SkPMColor* d = (SkPMColor*)dst;
    for (int i = 0; i < width; i++) {
        SkColor c = *src++;
        *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),
                                   SkColorGetG(c), SkColorGetB(c));
    }
}
示例#11
0
static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_unpremul(
        void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {

    // Use the masks to decode to the destination
    SkPMColor* dstPtr = (SkPMColor*) dstRow;
    INIT_RESULT_ALPHA;
    for (int i = 0; i < 3*width; i += 3) {
        uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
        uint8_t red = masks->getRed(p);
        uint8_t green = masks->getGreen(p);
        uint8_t blue = masks->getBlue(p);
        uint8_t alpha = masks->getAlpha(p);
        UPDATE_RESULT_ALPHA(alpha);
        dstPtr[i/3] = SkPackARGB32NoCheck(alpha, red, green, blue);
    }
    return COMPUTE_RESULT_ALPHA;
}
示例#12
0
inline uint32_t blendSrcOverDstNonPremultiplied(uint32_t src, uint32_t dst)
{
    uint8_t srcA = SkGetPackedA32(src);
    if (srcA == 0)
        return dst;

    uint8_t dstA = SkGetPackedA32(dst);
    uint8_t dstFactorA = (dstA * SkAlpha255To256(255 - srcA)) >> 8;
    ASSERT(srcA + dstFactorA < (1U << 8));
    uint8_t blendA = srcA + dstFactorA;
    unsigned scale = (1UL << 24) / blendA;

    uint8_t blendR = blendChannel(SkGetPackedR32(src), srcA, SkGetPackedR32(dst), dstFactorA, scale);
    uint8_t blendG = blendChannel(SkGetPackedG32(src), srcA, SkGetPackedG32(dst), dstFactorA, scale);
    uint8_t blendB = blendChannel(SkGetPackedB32(src), srcA, SkGetPackedB32(dst), dstFactorA, scale);

    return SkPackARGB32NoCheck(blendA, blendR, blendG, blendB);
}
示例#13
0
/*
 * Process the color table for the bmp input
 */
 bool SkBmpRLECodec::createColorTable(int* numColors) {
    // Allocate memory for color table
    uint32_t colorBytes = 0;
    SkPMColor colorTable[256];
    if (this->bitsPerPixel() <= 8) {
        // Inform the caller of the number of colors
        uint32_t maxColors = 1 << this->bitsPerPixel();
        if (NULL != numColors) {
            // We set the number of colors to maxColors in order to ensure
            // safe memory accesses.  Otherwise, an invalid pixel could
            // access memory outside of our color table array.
            *numColors = maxColors;
        }

        // Read the color table from the stream
        colorBytes = fNumColors * fBytesPerColor;
        SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
        if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) {
            SkCodecPrintf("Error: unable to read color table.\n");
            return false;
        }

        // Fill in the color table
        uint32_t i = 0;
        for (; i < fNumColors; i++) {
            uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor);
            uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1);
            uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2);
            colorTable[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
        }

        // To avoid segmentation faults on bad pixel data, fill the end of the
        // color table with black.  This is the same the behavior as the
        // chromium decoder.
        for (; i < maxColors; i++) {
            colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0);
        }

        // Set the color table
        fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors)));
    }

    // Check that we have not read past the pixel array offset
    if(fOffset < colorBytes) {
        // This may occur on OS 2.1 and other old versions where the color
        // table defaults to max size, and the bmp tries to use a smaller
        // color table.  This is invalid, and our decision is to indicate
        // an error, rather than try to guess the intended size of the
        // color table.
        SkCodecPrintf("Error: pixel data offset less than color table size.\n");
        return false;
    }

    // After reading the color table, skip to the start of the pixel array
    if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) {
        SkCodecPrintf("Error: unable to skip to image data.\n");
        return false;
    }

    // Return true on success
    return true;
}
示例#14
0
// This swizzles SkColor into the same component order as SkPMColor, but does not actually
// "pre" multiply the color components.
//
// This allows us to map directly to Sk4f, and eventually scale down to bytes to output a
// SkPMColor from the floats, without having to swizzle each time.
//
static uint32_t SkSwizzle_Color_to_PMColor(SkColor c) {
    return SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));
}
示例#15
0
void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint,
                  SkDevice* dstDevice, const IntSize& size)
{
    ASSERT(sourceRect.width() > 0);
    ASSERT(sourceRect.height() > 0);

    int originX = sourceRect.x();
    int destX = destPoint.x() + sourceRect.x();
    ASSERT(destX >= 0);
    ASSERT(destX < size.width());
    ASSERT(originX >= 0);
    ASSERT(originX < sourceRect.maxX());

    int endX = destPoint.x() + sourceRect.maxX();
    ASSERT(endX <= size.width());

    int numColumns = endX - destX;

    int originY = sourceRect.y();
    int destY = destPoint.y() + sourceRect.y();
    ASSERT(destY >= 0);
    ASSERT(destY < size.height());
    ASSERT(originY >= 0);
    ASSERT(originY < sourceRect.maxY());

    int endY = destPoint.y() + sourceRect.maxY();
    ASSERT(endY <= size.height());
    int numRows = endY - destY;

    unsigned srcBytesPerRow = 4 * sourceSize.width();

    SkBitmap deviceBitmap = dstDevice->accessBitmap(true);

    // If the device's bitmap doesn't have pixels we will make a temp and call writePixels on the device.
    bool temporaryBitmap = !!deviceBitmap.getTexture();
    SkBitmap destBitmap;

    if (temporaryBitmap) {
        destBitmap.setConfig(SkBitmap::kARGB_8888_Config, numColumns, numRows, srcBytesPerRow);
        if (!destBitmap.allocPixels())
            CRASH();
    } else
        deviceBitmap.extractSubset(&destBitmap, SkIRect::MakeXYWH(destX, destY, numColumns, numRows));

    // Whether we made a temporary or not destBitmap is always configured to be written at 0,0
    SkAutoLockPixels destAutoLock(destBitmap);
    const unsigned char* srcRow = source->data() + originY * srcBytesPerRow + originX * 4;
    for (int y = 0; y < numRows; ++y) {
        SkPMColor* destRow = destBitmap.getAddr32(0, y);
        for (int x = 0; x < numColumns; ++x) {
            const unsigned char* srcPixel = &srcRow[x * 4];
            if (multiplied == Unmultiplied) {
                unsigned char alpha = srcPixel[3];
                unsigned char r = SkMulDiv255Ceiling(srcPixel[0], alpha);
                unsigned char g = SkMulDiv255Ceiling(srcPixel[1], alpha);
                unsigned char b = SkMulDiv255Ceiling(srcPixel[2], alpha);
                destRow[x] = SkPackARGB32(alpha, r, g, b);
            } else
                destRow[x] = SkPackARGB32NoCheck(srcPixel[3], srcPixel[0], srcPixel[1], srcPixel[2]);
        }
        srcRow += srcBytesPerRow;
    }

    // If we used a temporary then write it to the device
    if (temporaryBitmap)
        dstDevice->writePixels(destBitmap, destX, destY);
}