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; }
/* 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; }
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); }
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; }
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; } }
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; }
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; }
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; }
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; }
static SkStream* create_black_image() { SkStream* stream = SkNEW_ARGS(SkMemoryStream, (1)); ((uint8_t*)stream->getMemoryBase())[0] = 0; return stream; }