wincodecs: Add encoder options for JPEG.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2017-07-28 14:41:13 -05:00 committed by Alexandre Julliard
parent 5d9a4c4dbd
commit 8648aaf86d
3 changed files with 64 additions and 1 deletions

View File

@ -60,6 +60,13 @@ WINE_DECLARE_DEBUG_CHANNEL(jpeg);
static void *libjpeg_handle; static void *libjpeg_handle;
static const WCHAR wszImageQuality[] = {'I','m','a','g','e','Q','u','a','l','i','t','y',0};
static const WCHAR wszBitmapTransform[] = {'B','i','t','m','a','p','T','r','a','n','s','f','o','r','m',0};
static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0};
static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0};
static const WCHAR wszJpegYCrCbSubsampling[] = {'J','p','e','g','Y','C','r','C','b','S','u','b','s','a','m','p','l','i','n','g',0};
static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0};
#define MAKE_FUNCPTR(f) static typeof(f) * p##f #define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(jpeg_CreateCompress); MAKE_FUNCPTR(jpeg_CreateCompress);
MAKE_FUNCPTR(jpeg_CreateDecompress); MAKE_FUNCPTR(jpeg_CreateDecompress);
@ -1407,6 +1414,7 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
{ {
JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); JpegEncoder *This = impl_from_IWICBitmapEncoder(iface);
HRESULT hr; HRESULT hr;
PROPBAG2 opts[6] = {{0}};
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
@ -1424,7 +1432,26 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
return WINCODEC_ERR_NOTINITIALIZED; return WINCODEC_ERR_NOTINITIALIZED;
} }
hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); opts[0].pstrName = (LPOLESTR)wszImageQuality;
opts[0].vt = VT_R4;
opts[0].dwType = PROPBAG2_TYPE_DATA;
opts[1].pstrName = (LPOLESTR)wszBitmapTransform;
opts[1].vt = VT_UI1;
opts[1].dwType = PROPBAG2_TYPE_DATA;
opts[2].pstrName = (LPOLESTR)wszLuminance;
opts[2].vt = VT_I4|VT_ARRAY;
opts[2].dwType = PROPBAG2_TYPE_DATA;
opts[3].pstrName = (LPOLESTR)wszChrominance;
opts[3].vt = VT_I4|VT_ARRAY;
opts[3].dwType = PROPBAG2_TYPE_DATA;
opts[4].pstrName = (LPOLESTR)wszJpegYCrCbSubsampling;
opts[4].vt = VT_UI1;
opts[4].dwType = PROPBAG2_TYPE_DATA;
opts[5].pstrName = (LPOLESTR)wszSuppressApp0;
opts[5].vt = VT_BOOL;
opts[5].dwType = PROPBAG2_TYPE_DATA;
hr = CreatePropertyBag2(opts, 6, ppIEncoderOptions);
if (FAILED(hr)) if (FAILED(hr))
{ {
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);

View File

@ -429,6 +429,12 @@ static const WCHAR wszTiffCompressionMethod[] = {'T','i','f','f','C','o','m','p'
static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0}; static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0};
static const WCHAR wszInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0}; static const WCHAR wszInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
static const WCHAR wszFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0}; static const WCHAR wszFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0};
static const WCHAR wszImageQuality[] = {'I','m','a','g','e','Q','u','a','l','i','t','y',0};
static const WCHAR wszBitmapTransform[] = {'B','i','t','m','a','p','T','r','a','n','s','f','o','r','m',0};
static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0};
static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0};
static const WCHAR wszJpegYCrCbSubsampling[] = {'J','p','e','g','Y','C','r','C','b','S','u','b','s','a','m','p','l','i','n','g',0};
static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0};
static const struct property_opt_test_data testdata_tiff_props[] = { static const struct property_opt_test_data testdata_tiff_props[] = {
{ wszTiffCompressionMethod, VT_UI1, VT_UI1, WICTiffCompressionDontCare }, { wszTiffCompressionMethod, VT_UI1, VT_UI1, WICTiffCompressionDontCare },
@ -442,6 +448,16 @@ static const struct property_opt_test_data testdata_png_props[] = {
{ NULL } { NULL }
}; };
static const struct property_opt_test_data testdata_jpeg_props[] = {
{ wszImageQuality, VT_R4, VT_EMPTY },
{ wszBitmapTransform, VT_UI1, VT_UI1, WICBitmapTransformRotate0 },
{ wszLuminance, VT_I4|VT_ARRAY, VT_EMPTY },
{ wszChrominance, VT_I4|VT_ARRAY, VT_EMPTY },
{ wszJpegYCrCbSubsampling, VT_UI1, VT_UI1, WICJpegYCrCbSubsamplingDefault, 0.0f, TRUE }, /* not supported on XP/2k3 */
{ wszSuppressApp0, VT_BOOL, VT_BOOL, FALSE },
{ NULL }
};
static int find_property_index(const WCHAR* name, PROPBAG2* all_props, int all_prop_cnt) static int find_property_index(const WCHAR* name, PROPBAG2* all_props, int all_prop_cnt)
{ {
int i; int i;
@ -566,6 +582,8 @@ static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *o
test_specific_encoder_properties(options, testdata_tiff_props, all_props, cProperties2); test_specific_encoder_properties(options, testdata_tiff_props, all_props, cProperties2);
else if (IsEqualCLSID(clsid_encoder, &CLSID_WICPngEncoder)) else if (IsEqualCLSID(clsid_encoder, &CLSID_WICPngEncoder))
test_specific_encoder_properties(options, testdata_png_props, all_props, cProperties2); test_specific_encoder_properties(options, testdata_png_props, all_props, cProperties2);
else if (IsEqualCLSID(clsid_encoder, &CLSID_WICJpegEncoder))
test_specific_encoder_properties(options, testdata_jpeg_props, all_props, cProperties2);
for (i=0; i < cProperties2; i++) for (i=0; i < cProperties2; i++)
{ {
@ -727,6 +745,13 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls
i++; i++;
} }
if (clsid_decoder == NULL)
{
IStream_Release(stream);
IWICBitmapEncoder_Release(encoder);
return;
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = IWICBitmapEncoder_Commit(encoder); hr = IWICBitmapEncoder_Commit(encoder);
@ -868,6 +893,9 @@ START_TEST(converter)
test_encoder(&testdata_24bppBGR, &CLSID_WICTiffEncoder, test_encoder(&testdata_24bppBGR, &CLSID_WICTiffEncoder,
&testdata_24bppBGR, &CLSID_WICTiffDecoder, "TIFF encoder 24bppBGR"); &testdata_24bppBGR, &CLSID_WICTiffDecoder, "TIFF encoder 24bppBGR");
test_encoder(&testdata_24bppBGR, &CLSID_WICJpegEncoder,
&testdata_24bppBGR, NULL, "JPEG encoder 24bppBGR");
test_multi_encoder(multiple_frames, &CLSID_WICTiffEncoder, test_multi_encoder(multiple_frames, &CLSID_WICTiffEncoder,
multiple_frames, &CLSID_WICTiffDecoder, NULL, NULL, "TIFF encoder multi-frame"); multiple_frames, &CLSID_WICTiffDecoder, NULL, NULL, "TIFF encoder multi-frame");

View File

@ -148,6 +148,14 @@ typedef enum WICComponentEnumerateOptions {
WICComponentEnumerateDisabled = 0x80000000 WICComponentEnumerateDisabled = 0x80000000
} WICComponentEnumerateOptions; } WICComponentEnumerateOptions;
typedef enum WICJpegYCrCbSubsamplingOption {
WICJpegYCrCbSubsamplingDefault = 0x00000000,
WICJpegYCrCbSubsampling420 = 0x00000001,
WICJpegYCrCbSubsampling422 = 0x00000002,
WICJpegYCrCbSubsampling444 = 0x00000003,
WICJpegYCrCbSubsampling440 = 0x00000004
} WICJpegYCrCbSubsamplingOption;
typedef enum WICPixelFormatNumericRepresentation { typedef enum WICPixelFormatNumericRepresentation {
WICPixelFormatNumericRepresentationUnspecified = 0x00000000, WICPixelFormatNumericRepresentationUnspecified = 0x00000000,
WICPixelFormatNumericRepresentationIndexed = 0x00000001, WICPixelFormatNumericRepresentationIndexed = 0x00000001,