Exemple #1
0
    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);
    }
}