void WEBPImageDecoder::readColorProfile(const uint8_t* data, size_t size) { WebPChunkIterator chunkIterator; WebPData inputData = { data, size }; WebPDemuxState state; WebPDemuxer* demuxer = WebPDemuxPartial(&inputData, &state); if (!WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunkIterator)) { WebPDemuxReleaseChunkIterator(&chunkIterator); WebPDemuxDelete(demuxer); return; } const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk.bytes); size_t profileSize = chunkIterator.chunk.size; // Only accept RGB color profiles from input class devices. bool ignoreProfile = false; if (profileSize < ImageDecoder::iccColorProfileHeaderLength) ignoreProfile = true; else if (!ImageDecoder::rgbColorProfile(profileData, profileSize)) ignoreProfile = true; else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileSize)) ignoreProfile = true; if (!ignoreProfile) createColorTransform(profileData, profileSize); WebPDemuxReleaseChunkIterator(&chunkIterator); WebPDemuxDelete(demuxer); }
void WEBPImageDecoder::readColorProfile() { WebPChunkIterator chunkIterator; if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { WebPDemuxReleaseChunkIterator(&chunkIterator); return; } const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk.bytes); size_t profileSize = chunkIterator.chunk.size; // Only accept RGB color profiles from input class devices. bool ignoreProfile = false; if (profileSize < ImageDecoder::iccColorProfileHeaderLength) ignoreProfile = true; else if (!ImageDecoder::rgbColorProfile(profileData, profileSize)) ignoreProfile = true; else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileSize)) ignoreProfile = true; if (!ignoreProfile) m_hasColorProfile = createColorTransform(profileData, profileSize); WebPDemuxReleaseChunkIterator(&chunkIterator); }
void WEBPImageDecoder::readColorProfile() { WebPChunkIterator chunkIterator; if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { WebPDemuxReleaseChunkIterator(&chunkIterator); return; } const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk.bytes); size_t profileSize = chunkIterator.chunk.size; setColorProfileAndComputeTransform(profileData, profileSize); WebPDemuxReleaseChunkIterator(&chunkIterator); }
static void ClearParams(void) { ClearPreviousPic(); WebPDataClear(&kParams.data); WebPDemuxReleaseIterator(&kParams.frameiter); WebPDemuxReleaseChunkIterator(&kParams.iccp); WebPDemuxDelete(kParams.dmux); kParams.dmux = NULL; }
/** * Uses libwebp to extract xmp metadata. */ const std::vector<uint8_t> extractMetadata( JNIEnv* env, std::vector<uint8_t>& image_data) { // Create WebPDemux from provided data. // It is "index" of all chunks. It stores // list of pointers to particular chunks, but does // not copy memory from provided WebPData. WebPData webpdata = {image_data.data(), image_data.size()}; // Thsnks to using RAII we do not need to worry about // releasing WebPDemuxer structure auto demux = std::unique_ptr<WebPDemuxer, decltype(&WebPDemuxDelete)>{ WebPDemux(&webpdata), WebPDemuxDelete}; THROW_AND_RETURNVAL_IF( demux == nullptr, "Could not create WebPDemux from image. This webp might be malformed.", {}); // find xmp chunk WebPChunkIterator chunk_iterator; if (!WebPDemuxGetChunk(demux.get(), "XMP ", 1, &chunk_iterator)) { // we failed to find "XMP " chunk - don't worry, maybe it was not // there. Let the transcode proceed WebPDemuxReleaseChunkIterator(&chunk_iterator); return {}; } // we managed to find "XMP " chunk, let's return its size and pointer to it const unsigned int metadata_length = chunk_iterator.chunk.size; const uint8_t* metadata_ptr = chunk_iterator.chunk.bytes; WebPDemuxReleaseChunkIterator(&chunk_iterator); // If XMP chunk contains no data then return nullptr. if (metadata_length == 0) { return {}; } return {metadata_ptr, metadata_ptr + metadata_length}; }
char* webpGetXMP(const uint8_t* data, size_t data_size, size_t* metadata_size) { char* metadata = NULL; WebPData webp_data = {data, data_size}; WebPDemuxer* demux = WebPDemux(&webp_data); uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); *metadata_size = 0; if(flags & XMP_FLAG) { WebPChunkIterator it; memset(&it, 0, sizeof(it)); if(WebPDemuxGetChunk(demux, "XMP ", 1, &it)) { if(it.chunk.bytes != NULL && it.chunk.size > 0) { metadata = (char*)malloc(it.chunk.size); memcpy(metadata, it.chunk.bytes, it.chunk.size); *metadata_size = it.chunk.size; } } WebPDemuxReleaseChunkIterator(&it); } WebPDemuxDelete(demux); return metadata; }
PyObject* _anim_decoder_get_chunk(PyObject* self, PyObject* args) { char* mode; WebPAnimDecoderObject* decp = (WebPAnimDecoderObject *)self; const WebPDemuxer* demux; WebPChunkIterator iter; PyObject *ret; if (!PyArg_ParseTuple(args, "s", &mode)) { return NULL; } demux = WebPAnimDecoderGetDemuxer(decp->dec); if (!WebPDemuxGetChunk(demux, mode, 1, &iter)) { Py_RETURN_NONE; } ret = PyBytes_FromStringAndSize((const char*)iter.chunk.bytes, iter.chunk.size); WebPDemuxReleaseChunkIterator(&iter); return ret; }