mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +01:00
wicdec: add ICC profile extraction
Change-Id: I4522cdd5a529f802f1eb566b6d94539612e0976b
This commit is contained in:
parent
522e9d6108
commit
e83ff7decd
@ -79,7 +79,6 @@ static int ReadYUV(FILE* in_file, WebPPicture* const pic) {
|
|||||||
static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||||
int keep_alpha, Metadata* const metadata) {
|
int keep_alpha, Metadata* const metadata) {
|
||||||
int ok;
|
int ok;
|
||||||
(void)metadata; // TODO(jzern): add metadata extraction using WIC
|
|
||||||
if (pic->width != 0 && pic->height != 0) {
|
if (pic->width != 0 && pic->height != 0) {
|
||||||
// If image size is specified, infer it as YUV format.
|
// If image size is specified, infer it as YUV format.
|
||||||
FILE* in_file = fopen(filename, "rb");
|
FILE* in_file = fopen(filename, "rb");
|
||||||
@ -91,7 +90,7 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
|||||||
fclose(in_file);
|
fclose(in_file);
|
||||||
} else {
|
} else {
|
||||||
// If no size specified, try to decode it using WIC.
|
// If no size specified, try to decode it using WIC.
|
||||||
ok = ReadPictureWithWIC(filename, pic, keep_alpha);
|
ok = ReadPictureWithWIC(filename, pic, keep_alpha, metadata);
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
||||||
@ -826,10 +825,10 @@ int main(int argc, const char *argv[]) {
|
|||||||
start = token + 1;
|
start = token + 1;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_WINCODEC_H
|
#ifdef HAVE_WINCODEC_H
|
||||||
if (keep_metadata != 0) {
|
if (keep_metadata != 0 && keep_metadata != METADATA_ICCP) {
|
||||||
// TODO(jzern): remove when -metadata is supported on all platforms.
|
// TODO(jzern): remove when -metadata is supported on all platforms.
|
||||||
fprintf(stderr, "Warning: -metadata is currently unsupported on this"
|
fprintf(stderr, "Warning: only ICC profile extraction is currently"
|
||||||
" platform. Ignoring this option!\n");
|
" supported on this platform!\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (!strcmp(argv[c], "-v")) {
|
} else if (!strcmp(argv[c], "-v")) {
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <wincodec.h>
|
#include <wincodec.h>
|
||||||
|
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
|
#include "./metadata.h"
|
||||||
|
|
||||||
#define IFS(fn) \
|
#define IFS(fn) \
|
||||||
do { \
|
do { \
|
||||||
@ -61,8 +62,76 @@ static HRESULT OpenInputStream(const char* filename, IStream** ppStream) {
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stores the first non-zero sized color profile from 'pFrame' to 'iccp'.
|
||||||
|
// Returns an HRESULT to indicate success or failure. The caller is responsible
|
||||||
|
// for freeing 'iccp->bytes' in either case.
|
||||||
|
static HRESULT ExtractICCP(IWICImagingFactory* const pFactory,
|
||||||
|
IWICBitmapFrameDecode* const pFrame,
|
||||||
|
MetadataPayload* const iccp) {
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
UINT i, count;
|
||||||
|
IWICColorContext** ppColorContext;
|
||||||
|
|
||||||
|
IFS(IWICBitmapFrameDecode_GetColorContexts(pFrame, 0, NULL, &count));
|
||||||
|
if (FAILED(hr) || count == 0) return hr;
|
||||||
|
|
||||||
|
ppColorContext = (IWICColorContext**)calloc(count, sizeof(*ppColorContext));
|
||||||
|
if (ppColorContext == NULL) return E_OUTOFMEMORY;
|
||||||
|
for (i = 0; SUCCEEDED(hr) && i < count; ++i) {
|
||||||
|
IFS(IWICImagingFactory_CreateColorContext(pFactory, &ppColorContext[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
UINT num_color_contexts;
|
||||||
|
IFS(IWICBitmapFrameDecode_GetColorContexts(pFrame,
|
||||||
|
count, ppColorContext,
|
||||||
|
&num_color_contexts));
|
||||||
|
for (i = 0; SUCCEEDED(hr) && i < num_color_contexts; ++i) {
|
||||||
|
WICColorContextType type;
|
||||||
|
IFS(IWICColorContext_GetType(ppColorContext[i], &type));
|
||||||
|
if (SUCCEEDED(hr) && type == WICColorContextProfile) {
|
||||||
|
UINT size;
|
||||||
|
IFS(IWICColorContext_GetProfileBytes(ppColorContext[i],
|
||||||
|
0, NULL, &size));
|
||||||
|
if (size > 0) {
|
||||||
|
iccp->bytes = (uint8_t*)malloc(size);
|
||||||
|
if (iccp->bytes == NULL) {
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iccp->size = size;
|
||||||
|
IFS(IWICColorContext_GetProfileBytes(ppColorContext[i],
|
||||||
|
(UINT)iccp->size, iccp->bytes,
|
||||||
|
&size));
|
||||||
|
if (SUCCEEDED(hr) && size != iccp->size) {
|
||||||
|
fprintf(stderr, "Warning! ICC profile size (%u) != expected (%u)\n",
|
||||||
|
size, iccp->size);
|
||||||
|
iccp->size = size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
if (ppColorContext[i] != NULL) IUnknown_Release(ppColorContext[i]);
|
||||||
|
}
|
||||||
|
free(ppColorContext);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ExtractMetadata(IWICImagingFactory* const pFactory,
|
||||||
|
IWICBitmapFrameDecode* const pFrame,
|
||||||
|
Metadata* const metadata) {
|
||||||
|
// TODO(jzern): add XMP/EXIF extraction.
|
||||||
|
const HRESULT hr = ExtractICCP(pFactory, pFrame, &metadata->iccp);
|
||||||
|
if (FAILED(hr)) MetadataFree(metadata);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
int ReadPictureWithWIC(const char* const filename,
|
int ReadPictureWithWIC(const char* const filename,
|
||||||
WebPPicture* const pic, int keep_alpha) {
|
WebPPicture* const pic, int keep_alpha,
|
||||||
|
Metadata* const metadata) {
|
||||||
// From Microsoft SDK 7.0a -- wincodec.h
|
// From Microsoft SDK 7.0a -- wincodec.h
|
||||||
// Create local copies for compatibility when building against earlier
|
// Create local copies for compatibility when building against earlier
|
||||||
// versions of the SDK.
|
// versions of the SDK.
|
||||||
@ -191,6 +260,12 @@ int ReadPictureWithWIC(const char* const filename,
|
|||||||
if (has_alpha && keep_alpha == 2) {
|
if (has_alpha && keep_alpha == 2) {
|
||||||
WebPCleanupTransparentArea(pic);
|
WebPCleanupTransparentArea(pic);
|
||||||
}
|
}
|
||||||
|
if (metadata != NULL) {
|
||||||
|
hr = ExtractMetadata(pFactory, pFrame, metadata);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
fprintf(stderr, "Error extracting image metadata using WIC!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup.
|
// Cleanup.
|
||||||
@ -204,10 +279,12 @@ int ReadPictureWithWIC(const char* const filename,
|
|||||||
}
|
}
|
||||||
#else // !HAVE_WINCODEC_H
|
#else // !HAVE_WINCODEC_H
|
||||||
int ReadPictureWithWIC(const char* const filename,
|
int ReadPictureWithWIC(const char* const filename,
|
||||||
struct WebPPicture* const pic, int keep_alpha) {
|
struct WebPPicture* const pic, int keep_alpha,
|
||||||
|
struct Metadata* const metadata) {
|
||||||
(void)filename;
|
(void)filename;
|
||||||
(void)pic;
|
(void)pic;
|
||||||
(void)keep_alpha;
|
(void)keep_alpha;
|
||||||
|
(void)metadata;
|
||||||
fprintf(stderr, "Windows Imaging Component (WIC) support not compiled. "
|
fprintf(stderr, "Windows Imaging Component (WIC) support not compiled. "
|
||||||
"Visual Studio and mingw-w64 builds support WIC. Make sure "
|
"Visual Studio and mingw-w64 builds support WIC. Make sure "
|
||||||
"wincodec.h detection is working correctly if using autoconf "
|
"wincodec.h detection is working correctly if using autoconf "
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct Metadata;
|
||||||
struct WebPPicture;
|
struct WebPPicture;
|
||||||
|
|
||||||
// Reads an image from 'filename', returning the decoded output in 'pic'.
|
// Reads an image from 'filename', returning the decoded output in 'pic'.
|
||||||
@ -21,7 +22,8 @@ struct WebPPicture;
|
|||||||
// RGBA otherwise it will be RGB.
|
// RGBA otherwise it will be RGB.
|
||||||
// Returns true on success.
|
// Returns true on success.
|
||||||
int ReadPictureWithWIC(const char* const filename,
|
int ReadPictureWithWIC(const char* const filename,
|
||||||
struct WebPPicture* const pic, int keep_alpha);
|
struct WebPPicture* const pic, int keep_alpha,
|
||||||
|
struct Metadata* const metadata);
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
Loading…
Reference in New Issue
Block a user