static HRESULT ExtractICCP()

in Extended/libwebp/imageio/wicdec.c [129:183]


static HRESULT ExtractICCP(IWICImagingFactory* const factory,
                           IWICBitmapFrameDecode* const frame,
                           MetadataPayload* const iccp) {
  HRESULT hr = S_OK;
  UINT i, count;
  IWICColorContext** color_contexts;

  IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count));
  if (FAILED(hr) || count == 0) return hr;

  color_contexts = (IWICColorContext**)calloc(count, sizeof(*color_contexts));
  if (color_contexts == NULL) return E_OUTOFMEMORY;
  for (i = 0; SUCCEEDED(hr) && i < count; ++i) {
    IFS(IWICImagingFactory_CreateColorContext(factory, &color_contexts[i]));
  }

  if (SUCCEEDED(hr)) {
    UINT num_color_contexts;
    IFS(IWICBitmapFrameDecode_GetColorContexts(frame,
                                               count, color_contexts,
                                               &num_color_contexts));
    assert(FAILED(hr) || num_color_contexts <= count);
    for (i = 0; SUCCEEDED(hr) && i < num_color_contexts; ++i) {
      WICColorContextType type;
      IFS(IWICColorContext_GetType(color_contexts[i], &type));
      if (SUCCEEDED(hr) && type == WICColorContextProfile) {
        UINT size;
        IFS(IWICColorContext_GetProfileBytes(color_contexts[i],
                                             0, NULL, &size));
        if (SUCCEEDED(hr) && size > 0) {
          iccp->bytes = (uint8_t*)malloc(size);
          if (iccp->bytes == NULL) {
            hr = E_OUTOFMEMORY;
            break;
          }
          iccp->size = size;
          IFS(IWICColorContext_GetProfileBytes(color_contexts[i],
                                               (UINT)iccp->size, iccp->bytes,
                                               &size));
          if (SUCCEEDED(hr) && size != iccp->size) {
            fprintf(stderr, "Warning! ICC profile size (%u) != expected (%u)\n",
                    size, (uint32_t)iccp->size);
            iccp->size = size;
          }
          break;
        }
      }
    }
  }
  for (i = 0; i < count; ++i) {
    if (color_contexts[i] != NULL) IUnknown_Release(color_contexts[i]);
  }
  free(color_contexts);
  return hr;
}