virtual bool peek(const char tag[], const void* data, size_t length) { if (strcmp("npTc", tag) == 0 && length >= sizeof(Res_png_9patch)) { Res_png_9patch* patch = (Res_png_9patch*) data; size_t patchSize = patch->serializedSize(); assert(length == patchSize); // You have to copy the data because it is owned by the png reader Res_png_9patch* patchNew = (Res_png_9patch*) malloc(patchSize); memcpy(patchNew, patch, patchSize); // this relies on deserialization being done in place Res_png_9patch::deserialize(patchNew); patchNew->fileToDevice(); if (fPatchIsValid) { free(fPatch); } fPatch = patchNew; //printf("9patch: (%d,%d)-(%d,%d)\n", // fPatch.sizeLeft, fPatch.sizeTop, // fPatch.sizeRight, fPatch.sizeBottom); fPatchIsValid = true; // now update our host to force index or 32bit config // 'cause we don't want 565 predithered, since as a 9patch, we know // we will be stretched, and therefore we want to dither afterwards. static const SkBitmap::Config gNo565Pref[] = { SkBitmap::kIndex8_Config, SkBitmap::kIndex8_Config, SkBitmap::kARGB_8888_Config, SkBitmap::kARGB_8888_Config, SkBitmap::kARGB_8888_Config, SkBitmap::kARGB_8888_Config, }; fHost->setPrefConfigTable(gNo565Pref); } else { fPatch = NULL; } return true; // keep on decoding }
void ImageSource::setData(SharedBuffer* data, bool allDataReceived) { #ifdef ANDROID_ANIMATED_GIF // This is only necessary if we allow ourselves to partially decode GIF bool disabledAnimatedGif = false; if (m_decoder.m_gifDecoder && !m_decoder.m_gifDecoder->failed()) { m_decoder.m_gifDecoder->setData(data, allDataReceived); if (!allDataReceived || m_decoder.m_gifDecoder->frameCount() != 1) return; disabledAnimatedGif = true; delete m_decoder.m_gifDecoder; m_decoder.m_gifDecoder = 0; } #endif if (NULL == m_decoder.m_image #ifdef ANDROID_ANIMATED_GIF && !m_decoder.m_gifDecoder #endif ) { SkBitmap tmp; SkMemoryStream stream(data->data(), data->size(), false); SkImageDecoder* codec = SkImageDecoder::Factory(&stream); if (!codec) return; SkAutoTDelete<SkImageDecoder> ad(codec); // FOR KITKAT MR2 INTEGRATION //codec->setPrefConfigTable(gPrefConfigTable); SkImageDecoder::PrefConfigTable configTable; configTable.fPrefFor_8Index_NoAlpha_src = gPrefConfigTable[0]; configTable.fPrefFor_8Index_YesAlpha_src = gPrefConfigTable[1]; configTable.fPrefFor_8Gray_src = SkBitmap::kNo_Config; configTable.fPrefFor_8bpc_NoAlpha_src = gPrefConfigTable[4]; configTable.fPrefFor_8bpc_YesAlpha_src = gPrefConfigTable[5]; codec->setPrefConfigTable(configTable); // FOR KITKAT MR2 INTEGRATION if (!codec->decode(&stream, &tmp, SkImageDecoder::kDecodeBounds_Mode)) return; int origW = tmp.width(); int origH = tmp.height(); #ifdef ANDROID_ANIMATED_GIF // First, check to see if this is an animated GIF const char* contents = data->data(); if (data->size() > 3 && strncmp(contents, "GIF8", 4) == 0 && should_use_animated_gif(origW, origH) && !disabledAnimatedGif) { // This means we are looking at a GIF, so create special // GIF Decoder // Need to wait for all data received if we are assigning an // allocator (which we are not at the moment). if (!m_decoder.m_gifDecoder /*&& allDataReceived*/) m_decoder.m_gifDecoder = new GIFImageDecoder(m_alphaOption, m_gammaAndColorProfileOption); int frameCount = 0; if (!m_decoder.m_gifDecoder->failed()) { m_decoder.m_gifDecoder->setData(data, allDataReceived); if (!allDataReceived) return; frameCount = m_decoder.m_gifDecoder->frameCount(); } if (frameCount != 1) return; delete m_decoder.m_gifDecoder; m_decoder.m_gifDecoder = 0; } #endif int sampleSize = computeSampleSize(tmp); if (sampleSize > 1) { codec->setSampleSize(sampleSize); stream.rewind(); if (!codec->decode(&stream, &tmp, SkImageDecoder::kDecodeBounds_Mode)) { return; } } m_decoder.m_image = new PrivateAndroidImageSourceRec(tmp, origW, origH, sampleSize); // SkDebugf("----- started: [%d %d] %s\n", origW, origH, m_decoder.m_url.c_str()); } PrivateAndroidImageSourceRec* decoder = m_decoder.m_image; if (allDataReceived && decoder && !decoder->fAllDataReceived) { decoder->fAllDataReceived = true; SkBitmap* bm = &decoder->bitmap(); // 4.2 Merge BEGIN << //Following code removed in 4.2 // SkPixelRef* ref = convertToRLE(bm, data->data(), data->size()); //4.2 Merge : removed in 4.2 // if (ref) { // bm->setPixelRef(ref)->unref(); // } else { // 4.2 Merge END >> BitmapAllocatorAndroid alloc(data, decoder->fSampleSize); if (!alloc.allocPixelRef(bm, NULL)) { return; } SkPixelRef* ref = bm->pixelRef();//4.2 Merge // }//4.3 Merge : removed in 4.2 // we promise to never change the pixels (makes picture recording fast) ref->setImmutable(); // give it the URL if we have one ref->setURI(m_decoder.m_url); } }