diff --git a/dlls/windowscodecs/jpegformat.c b/dlls/windowscodecs/jpegformat.c index acc262e860d..014620fa414 100644 --- a/dlls/windowscodecs/jpegformat.c +++ b/dlls/windowscodecs/jpegformat.c @@ -60,6 +60,13 @@ WINE_DECLARE_DEBUG_CHANNEL(jpeg); 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 MAKE_FUNCPTR(jpeg_CreateCompress); MAKE_FUNCPTR(jpeg_CreateDecompress); @@ -1407,6 +1414,7 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, { JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); HRESULT hr; + PROPBAG2 opts[6] = {{0}}; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); @@ -1424,7 +1432,26 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, 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)) { LeaveCriticalSection(&This->lock); diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c index fba7fc73ac7..041ca96c8ec 100644 --- a/dlls/windowscodecs/tests/converter.c +++ b/dlls/windowscodecs/tests/converter.c @@ -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 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 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[] = { { wszTiffCompressionMethod, VT_UI1, VT_UI1, WICTiffCompressionDontCare }, @@ -442,6 +448,16 @@ static const struct property_opt_test_data testdata_png_props[] = { { 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) { 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); else if (IsEqualCLSID(clsid_encoder, &CLSID_WICPngEncoder)) 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++) { @@ -727,6 +745,13 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls i++; } + if (clsid_decoder == NULL) + { + IStream_Release(stream); + IWICBitmapEncoder_Release(encoder); + return; + } + if (SUCCEEDED(hr)) { hr = IWICBitmapEncoder_Commit(encoder); @@ -868,6 +893,9 @@ START_TEST(converter) test_encoder(&testdata_24bppBGR, &CLSID_WICTiffEncoder, &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, multiple_frames, &CLSID_WICTiffDecoder, NULL, NULL, "TIFF encoder multi-frame"); diff --git a/include/wincodec.idl b/include/wincodec.idl index 1bbdab90c4a..e727cbdd5bb 100644 --- a/include/wincodec.idl +++ b/include/wincodec.idl @@ -148,6 +148,14 @@ typedef enum WICComponentEnumerateOptions { WICComponentEnumerateDisabled = 0x80000000 } WICComponentEnumerateOptions; +typedef enum WICJpegYCrCbSubsamplingOption { + WICJpegYCrCbSubsamplingDefault = 0x00000000, + WICJpegYCrCbSubsampling420 = 0x00000001, + WICJpegYCrCbSubsampling422 = 0x00000002, + WICJpegYCrCbSubsampling444 = 0x00000003, + WICJpegYCrCbSubsampling440 = 0x00000004 +} WICJpegYCrCbSubsamplingOption; + typedef enum WICPixelFormatNumericRepresentation { WICPixelFormatNumericRepresentationUnspecified = 0x00000000, WICPixelFormatNumericRepresentationIndexed = 0x00000001,