示例#1
0
static SkStream* extract_argb8888_data(const SkBitmap& bitmap,
                                       const SkIRect& srcRect,
                                       bool extractAlpha,
                                       bool* isOpaque,
                                       bool* isTransparent) {
    size_t streamSize = extractAlpha ? srcRect.width() * srcRect.height()
                                     : get_uncompressed_size(bitmap, srcRect);
    SkStream* stream = SkNEW_ARGS(SkMemoryStream, (streamSize));
    uint8_t* dst = (uint8_t*)stream->getMemoryBase();

    const SkUnPreMultiply::Scale* scaleTable = SkUnPreMultiply::GetScaleTable();

    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++) {
            SkPMColor c = src[x];
            U8CPU alpha = SkGetPackedA32(c);
            if (extractAlpha) {
                *isOpaque &= alpha == SK_AlphaOPAQUE;
                *isTransparent &= alpha == SK_AlphaTRANSPARENT;
                *dst++ = alpha;
            } else {
                if (SK_AlphaTRANSPARENT == alpha) {
                    // It is necessary to average the color component of
                    // transparent pixels with their surrounding neighbors
                    // since the PDF renderer may separately re-sample the
                    // alpha and color channels when the image is not
                    // displayed at its native resolution. Since an alpha of
                    // zero gives no information about the color component,
                    // the pathological case is a white image with sharp
                    // transparency bounds - the color channel goes to black,
                    // and the should-be-transparent pixels are rendered
                    // as grey because of the separate soft mask and color
                    // resizing.
                    c = get_argb8888_neighbor_avg_color(bitmap, x, y);
                    *dst++ = SkGetPackedR32(c);
                    *dst++ = SkGetPackedG32(c);
                    *dst++ = SkGetPackedB32(c);
                } else {
                    SkUnPreMultiply::Scale s = scaleTable[alpha];
                    *dst++ = SkUnPreMultiply::ApplyScale(s, SkGetPackedR32(c));
                    *dst++ = SkUnPreMultiply::ApplyScale(s, SkGetPackedG32(c));
                    *dst++ = SkUnPreMultiply::ApplyScale(s, SkGetPackedB32(c));
                }
            }
        }
    }
    SkASSERT(dst == streamSize + (uint8_t*)stream->getMemoryBase());
    return stream;
}
示例#2
0
/*  make a deep copy of the asset, and return it as a stream, or NULL if there
    was an error.
 */
SkStream*
BitmapFactoryGlue::copyAssetToStream(Asset& asset)
{
	// if we could "ref/reopen" the asset, we may not need to copy it here
	off64_t size = asset.seek(0, SEEK_SET);
	if ((off64_t)-1 == size) {
		SkDebugf("---- copyAsset: asset rewind failed\n");
		return NULL;
	}

	size = asset.getLength();
	if (size <= 0) {
		SkDebugf("---- copyAsset: asset->getLength() returned %d\n", size);
		return NULL;
	}

	SkStream* stream = new SkMemoryStream(size);
	void* data = const_cast<void*>(stream->getMemoryBase());
	off64_t len = asset.read(data, size);
	if (len != size) {
		SkDebugf("---- copyAsset: asset->read(%d) returned %d\n", size, len);
		delete stream;
		stream = NULL;
	}
	return stream;
}
示例#3
0
static void delete_stream_proc(void* info, const void* addr, size_t size) {
    SkASSERT(info);
    SkStream* stream = (SkStream*)info;
    SkASSERT(stream->getMemoryBase() == addr);
    SkASSERT(stream->getLength() == size);
    SkDELETE(stream);
}
示例#4
0
static SkStream* extract_argb8888_data(const SkBitmap& bitmap,
                                       const SkIRect& srcRect,
                                       bool extractAlpha,
                                       bool* isOpaque,
                                       bool* isTransparent) {
    SkStream* stream;
    if (extractAlpha) {
        stream = SkNEW_ARGS(SkMemoryStream,
                            (srcRect.width() * srcRect.height()));
    } else {
        stream = SkNEW_ARGS(SkMemoryStream,
                            (get_uncompressed_size(bitmap, srcRect)));
    }
    uint8_t* dst = (uint8_t*)stream->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++) {
            if (extractAlpha) {
                dst[0] = SkGetPackedA32(src[x]);
                *isOpaque &= dst[0] == SK_AlphaOPAQUE;
                *isTransparent &= dst[0] == SK_AlphaTRANSPARENT;
                dst++;
            } else {
                dst[0] = SkGetPackedR32(src[x]);
                dst[1] = SkGetPackedG32(src[x]);
                dst[2] = SkGetPackedB32(src[x]);
                dst += 3;
            }
        }
    }
    return stream;
}
示例#5
0
static SkStream* extract_argb4444_data(const SkBitmap& bitmap,
                                       const SkIRect& srcRect,
                                       bool extractAlpha,
                                       bool* isOpaque,
                                       bool* isTransparent) {
    SkStream* stream;
    uint8_t* dst = NULL;
    if (extractAlpha) {
        const int alphaRowBytes = (srcRect.width() + 1) / 2;
        stream = SkNEW_ARGS(SkMemoryStream,
                            (alphaRowBytes * srcRect.height()));
    } else {
        stream = SkNEW_ARGS(SkMemoryStream,
                            (get_uncompressed_size(bitmap, srcRect)));
    }
    dst = (uint8_t*)stream->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) {
            if (extractAlpha) {
                dst[0] = (SkGetPackedA4444(src[x]) << 4) |
                    SkGetPackedA4444(src[x + 1]);
                *isOpaque &= dst[0] == SK_AlphaOPAQUE;
                *isTransparent &= dst[0] == SK_AlphaTRANSPARENT;
                dst++;
            } else {
                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;
            }
        }
        if (srcRect.width() & 1) {
            if (extractAlpha) {
                dst[0] = (SkGetPackedA4444(src[x]) << 4);
                *isOpaque &= dst[0] == (SK_AlphaOPAQUE & 0xF0);
                *isTransparent &= dst[0] == (SK_AlphaTRANSPARENT & 0xF0);
                dst++;

            } else {
                dst[0] = (SkGetPackedR4444(src[x]) << 4) |
                    SkGetPackedG4444(src[x]);
                dst[1] = (SkGetPackedB4444(src[x]) << 4);
                dst += 2;
            }
        }
    }
    return stream;
}
// Will return 0 on failure
static SkFaceRec* ref_ft_face(uint32_t fontID) {
    SkFaceRec* rec = gFaceRecHead;
    while (rec) {
        if (rec->fFontID == fontID) {
            SkASSERT(rec->fFace);
            rec->fRefCnt += 1;
            return rec;
        }
        rec = rec->fNext;
    }

    SkStream* strm = SkFontHost::OpenStream(fontID);
    if (NULL == strm) {
        SkDEBUGF(("SkFontHost::OpenStream failed opening %x\n", fontID));
        return 0;
    }

    // this passes ownership of strm to the rec
    rec = SkNEW_ARGS(SkFaceRec, (strm, fontID));

    FT_Open_Args    args;
    memset(&args, 0, sizeof(args));
    const void* memoryBase = strm->getMemoryBase();

    if (NULL != memoryBase) {
//printf("mmap(%s)\n", keyString.c_str());
        args.flags = FT_OPEN_MEMORY;
        args.memory_base = (const FT_Byte*)memoryBase;
        args.memory_size = strm->getLength();
    } else {
//printf("fopen(%s)\n", keyString.c_str());
        args.flags = FT_OPEN_STREAM;
        args.stream = &rec->fFTStream;
    }

    int face_index;
    int length = SkFontHost::GetFileName(fontID, NULL, 0, &face_index);
    FT_Error err = FT_Open_Face(gFTLibrary, &args, length ? face_index : 0,
                                &rec->fFace);

    if (err) {    // bad filename, try the default font
        fprintf(stderr, "ERROR: unable to open font '%x'\n", fontID);
        SkDELETE(rec);
        return 0;
    } else {
        SkASSERT(rec->fFace);
        //fprintf(stderr, "Opened font '%s'\n", filename.c_str());
        rec->fNext = gFaceRecHead;
        gFaceRecHead = rec;
        rec->fRefCnt = 1;
        return rec;
    }
}
示例#7
0
static SkStream* extract_index8_image(const SkBitmap& bitmap,
                                      const SkIRect& srcRect) {
    const int rowBytes = srcRect.width();
    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
                                  (get_uncompressed_size(bitmap, srcRect)));
    uint8_t* dst = (uint8_t*)stream->getMemoryBase();

    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
        memcpy(dst, bitmap.getAddr8(srcRect.fLeft, y), rowBytes);
        dst += rowBytes;
    }
    return stream;
}
示例#8
0
static SkStream* extract_gray8_image(const SkBitmap& bitmap, const SkIRect& srcRect) {
    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
                                  (get_uncompressed_size(bitmap, srcRect)));
    uint8_t* dst = (uint8_t*)stream->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++) {
            dst[0] = dst[1] = dst[2] = src[x];
            dst += 3;
        }
    }
    return stream;
}
示例#9
0
static SkStream* extract_a8_alpha(const SkBitmap& bitmap,
                                  const SkIRect& srcRect,
                                  bool* isOpaque,
                                  bool* isTransparent) {
    const int alphaRowBytes = srcRect.width();
    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
                                  (alphaRowBytes * srcRect.height()));
    uint8_t* alphaDst = (uint8_t*)stream->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];
            *isOpaque &= alphaDst[0] == SK_AlphaOPAQUE;
            *isTransparent &= alphaDst[0] == SK_AlphaTRANSPARENT;
            alphaDst++;
        }
    }
    return stream;
}
示例#10
0
SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const {
    SkStream* stream = this->getLocalStream();
    if (stream) {
        // should have been provided by CreateFromStream()
        *ttcIndex = 0;

        SkAutoTUnref<SkStream> dupStream(stream->duplicate());
        if (dupStream) {
            return dupStream.detach();
        }

        // TODO: update interface use, remove the following code in this block.
        size_t length = stream->getLength();

        const void* memory = stream->getMemoryBase();
        if (NULL != memory) {
            return new SkMemoryStream(memory, length, true);
        }

        SkAutoTMalloc<uint8_t> allocMemory(length);
        stream->rewind();
        if (length == stream->read(allocMemory.get(), length)) {
            SkAutoTUnref<SkMemoryStream> copyStream(new SkMemoryStream());
            copyStream->setMemoryOwned(allocMemory.detach(), length);
            return copyStream.detach();
        }

        stream->rewind();
        stream->ref();
    } else {
        SkAutoTUnref<SkFontConfigInterface> fci(RefFCI());
        if (NULL == fci.get()) {
            return NULL;
        }
        stream = fci->openStream(this->getIdentity());
        *ttcIndex = this->getIdentity().fTTCIndex;
    }
    return stream;
}
示例#11
0
static SkStream* create_black_image() {
    SkStream* stream = SkNEW_ARGS(SkMemoryStream, (1));
    ((uint8_t*)stream->getMemoryBase())[0] = 0;
    return stream;
}