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); } }
void ImageSource::setData(SharedBuffer* data, bool allDataReceived) { #ifdef ANDROID_ANIMATED_GIF // This is only necessary if we allow ourselves to partially decode GIF if (m_decoder.m_gifDecoder && !m_decoder.m_gifDecoder->failed()) { m_decoder.m_gifDecoder->setData(data, allDataReceived); return; } #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); SkAutoTDelete<SkImageDecoder> ad(codec); if (!codec || !codec->decode(&stream, &tmp, SkBitmap::kNo_Config, 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 Vector<char>& buffer = data->buffer(); const char* contents = buffer.data(); if (buffer.size() > 3 && strncmp(contents, "GIF8", 4) == 0 && should_use_animated_gif(origW, origH)) { // 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(); if (!m_decoder.m_gifDecoder->failed()) m_decoder.m_gifDecoder->setData(data, allDataReceived); return; } #endif int sampleSize = computeSampleSize(tmp); if (sampleSize > 1) { codec->setSampleSize(sampleSize); stream.rewind(); if (!codec->decode(&stream, &tmp, SkBitmap::kNo_Config, 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->fAllDataReceived) { decoder->fAllDataReceived = true; SkBitmap* bm = &decoder->bitmap(); SkPixelRef* ref = convertToRLE(bm, data->data(), data->size()); if (ref) { bm->setPixelRef(ref)->unref(); } else { BitmapAllocatorAndroid alloc(data, decoder->fSampleSize); if (!alloc.allocPixelRef(bm, NULL)) { return; } ref = bm->pixelRef(); } // 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); } }