コード例 #1
0
ファイル: webp.c プロジェクト: beforewind/webp
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;
}
コード例 #2
0
ファイル: webp_codec.cpp プロジェクト: 03050903/fresco
/**
 * 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};
}
コード例 #3
0
ファイル: qwebphandler.cpp プロジェクト: ArchangelSDY/qwebpa
bool QWebpHandler::ensureScanned() const
{
    if (m_scanState != ScanNotScanned)
        return m_scanState == ScanSuccess;

    m_scanState = ScanError;

    if (device()->isSequential()) {
        qWarning() << "Sequential devices are not supported";
        return false;
    }

    QWebpHandler *that = const_cast<QWebpHandler *>(this);

    // FIXME: should not read all when scanning
    that->m_rawData = device()->readAll();
    that->m_webpData.bytes = reinterpret_cast<const uint8_t *>(m_rawData.data());
    that->m_webpData.size = m_rawData.size();

    that->m_demuxer = WebPDemux(&m_webpData);
    if (m_demuxer == NULL)
        return false;

    that->m_flags = WebPDemuxGetI(m_demuxer, WEBP_FF_FORMAT_FLAGS);
    that->m_width = WebPDemuxGetI(m_demuxer, WEBP_FF_CANVAS_WIDTH);
    that->m_height = WebPDemuxGetI(m_demuxer, WEBP_FF_CANVAS_HEIGHT);
    that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
    that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);

    if (!WebPDemuxGetFrame(m_demuxer, 1, &(that->m_iter))) {
        return false;
    }

    m_scanState = ScanSuccess;
    return true;
}