62 0, 0, { (
DWORD_PTR)(__FILE__
": init_tiff_cs") }
64static CRITICAL_SECTION init_tiff_cs = { &init_tiff_cs_debug, -1, 0, 0, 0, 0 };
66static const WCHAR wszTiffCompressionMethod[] = {
'T',
'i',
'f',
'f',
'C',
'o',
'm',
'p',
'r',
'e',
's',
's',
'i',
'o',
'n',
'M',
'e',
't',
'h',
'o',
'd',0};
67static const WCHAR wszCompressionQuality[] = {
'C',
'o',
'm',
'p',
'r',
'e',
's',
's',
'i',
'o',
'n',
'Q',
'u',
'a',
'l',
'i',
't',
'y',0};
69static void *libtiff_handle;
70#define MAKE_FUNCPTR(f) static typeof(f) * p##f
86static void *load_libtiff(
void)
92 if (!libtiff_handle &&
95 void * (*pTIFFSetWarningHandler)(
void *);
96 void * (*pTIFFSetWarningHandlerExt)(
void *);
98#define LOAD_FUNCPTR(f) \
99 if((p##f = wine_dlsym(libtiff_handle, #f, NULL, 0)) == NULL) { \
100 ERR("failed to load symbol %s\n", #f); \
101 libtiff_handle = NULL; \
102 LeaveCriticalSection(&init_tiff_cs); \
120 if ((pTIFFSetWarningHandler =
wine_dlsym(libtiff_handle,
"TIFFSetWarningHandler",
NULL, 0)))
121 pTIFFSetWarningHandler(
NULL);
122 if ((pTIFFSetWarningHandlerExt =
wine_dlsym(libtiff_handle,
"TIFFSetWarningHandlerExt",
NULL, 0)))
123 pTIFFSetWarningHandlerExt(
NULL);
151 return bytes_written;
175 ERR(
"unknown whence value %i\n", whence);
184static int tiff_stream_close(
thandle_t client_data)
196 hr = IStream_Stat(
stream, &statstg, STATFLAG_NONAME);
220 return pTIFFClientOpen(
"<IStream object>",
mode,
stream, tiff_stream_read,
221 tiff_stream_write, (
void *)tiff_stream_seek, tiff_stream_close,
222 (
void *)tiff_stream_size, (
void *)tiff_stream_map, (
void *)tiff_stream_unmap);
242 int invert_grayscale;
244 UINT tile_width, tile_height;
249 UINT resolution_unit;
259 tiff_decode_info decode_info;
260 INT cached_tile_x, cached_tile_y;
264static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl;
265static const IWICMetadataBlockReaderVtbl TiffFrameDecode_BlockVtbl;
282static HRESULT tiff_get_decode_info(
TIFF *
tiff, tiff_decode_info *decode_info)
285 uint16 extra_sample_count, extra_sample, *extra_samples;
288 decode_info->indexed = 0;
289 decode_info->reverse_bgr = 0;
290 decode_info->invert_grayscale = 0;
291 decode_info->tiled = 0;
292 decode_info->source_bpp = 0;
297 WARN(
"missing PhotometricInterpretation tag\n");
303 decode_info->bps = bps;
307 decode_info->samples =
samples;
314 if (!
ret) planar = 1;
317 FIXME(
"unhandled planar configuration %u\n", planar);
321 decode_info->planar = planar;
323 TRACE(
"planar %u, photometric %u, samples %u, bps %u\n", planar, photometric,
samples, bps);
328 decode_info->invert_grayscale = 1;
336 extra_sample_count = 1;
338 extra_samples = &extra_sample;
343 FIXME(
"unhandled %dbpp sample count %u\n", bps,
samples);
347 decode_info->bpp = bps *
samples;
348 decode_info->source_bpp = decode_info->bpp;
357 decode_info->format = &GUID_WICPixelFormatBlackWhite;
362 FIXME(
"unhandled 4bpp grayscale sample count %u\n",
samples);
365 decode_info->format = &GUID_WICPixelFormat4bppGray;
369 decode_info->format = &GUID_WICPixelFormat8bppGray;
372 decode_info->bpp = 32;
374 switch(extra_samples[0])
377 decode_info->format = &GUID_WICPixelFormat32bppPBGRA;
381 decode_info->format = &GUID_WICPixelFormat32bppBGRA;
384 FIXME(
"unhandled extra sample type %u\n", extra_samples[0]);
392 FIXME(
"unhandled 16bpp grayscale sample count %u\n",
samples);
395 decode_info->format = &GUID_WICPixelFormat16bppGray;
400 FIXME(
"unhandled 32bpp grayscale sample count %u\n",
samples);
403 decode_info->format = &GUID_WICPixelFormat32bppGrayFloat;
406 WARN(
"unhandled greyscale bit count %u\n", bps);
416 extra_sample_count = 1;
418 extra_samples = &extra_sample;
428 decode_info->source_bpp = bps *
samples;
434 decode_info->reverse_bgr = 1;
436 decode_info->format = &GUID_WICPixelFormat24bppBGR;
438 switch(extra_samples[0])
441 decode_info->format = &GUID_WICPixelFormat32bppPBGRA;
445 decode_info->format = &GUID_WICPixelFormat32bppBGRA;
448 FIXME(
"unhandled extra sample type %i\n", extra_samples[0]);
454 decode_info->format = &GUID_WICPixelFormat48bppRGB;
456 switch(extra_samples[0])
459 decode_info->format = &GUID_WICPixelFormat64bppPRGBA;
463 decode_info->format = &GUID_WICPixelFormat64bppRGBA;
466 FIXME(
"unhandled extra sample type %i\n", extra_samples[0]);
473 FIXME(
"unhandled 32bpp RGB sample count %u\n",
samples);
476 decode_info->format = &GUID_WICPixelFormat128bppRGBAFloat;
479 WARN(
"unhandled RGB bit count %u\n", bps);
490 decode_info->indexed = 1;
491 decode_info->bpp = bps;
495 decode_info->format = &GUID_WICPixelFormat1bppIndexed;
498 decode_info->format = &GUID_WICPixelFormat2bppIndexed;
501 decode_info->format = &GUID_WICPixelFormat4bppIndexed;
504 decode_info->format = &GUID_WICPixelFormat8bppIndexed;
507 FIXME(
"unhandled indexed bit count %u\n", bps);
515 FIXME(
"unhandled Separated sample count %u\n",
samples);
519 decode_info->bpp = bps *
samples;
523 decode_info->format = &GUID_WICPixelFormat32bppCMYK;
526 decode_info->format = &GUID_WICPixelFormat64bppCMYK;
530 WARN(
"unhandled Separated bit count %u\n", bps);
539 FIXME(
"unhandled PhotometricInterpretation %u\n", photometric);
546 WARN(
"missing image width\n");
553 WARN(
"missing image length\n");
559 decode_info->tiled = 1;
564 WARN(
"missing tile height\n");
568 decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8);
569 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
570 decode_info->tiles_across = (decode_info->width + decode_info->tile_width - 1) / decode_info->tile_width;
574 if (decode_info->tile_height > decode_info->height)
575 decode_info->tile_height = decode_info->height;
576 decode_info->tile_width = decode_info->width;
577 decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8);
578 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
583 decode_info->tile_height = decode_info->height;
584 decode_info->tile_width = decode_info->width;
585 decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8);
586 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
589 decode_info->resolution_unit = 0;
595 WARN(
"missing X resolution\n");
601 decode_info->xres = 0.0;
607 WARN(
"missing Y resolution\n");
611 decode_info->yres = 0.0;
628 *
ppv = &
This->IWICBitmapDecoder_iface;
645 TRACE(
"(%p) refcount=%u\n", iface,
ref);
655 TRACE(
"(%p) refcount=%u\n", iface,
ref);
659 if (
This->tiff) pTIFFClose(
This->tiff);
660 if (
This->stream) IStream_Release(
This->stream);
661 This->lock.DebugInfo->Spare[0] = 0;
692 tiff_decode_info decode_info;
695 TRACE(
"(%p,%p,%x)\n", iface, pIStream, cacheOptions);
699 if (
This->initialized)
705 tiff = tiff_open_stream(pIStream,
"r");
713 hr = tiff_get_decode_info(
tiff, &decode_info);
721 This->stream = pIStream;
722 IStream_AddRef(pIStream);
731 GUID *pguidContainerFormat)
735 memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff,
sizeof(
GUID));
742 TRACE(
"(%p,%p)\n", iface, ppIDecoderInfo);
757 TRACE(
"(%p,%p)\n", iface, ppIMetadataQueryReader);
761 *ppIMetadataQueryReader =
NULL;
768 TRACE(
"(%p,%p)\n", iface, ppIBitmapSource);
772 *ppIBitmapSource =
NULL;
779 FIXME(
"(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
786 TRACE(
"(%p,%p)\n", iface, ppIThumbnail);
790 *ppIThumbnail =
NULL;
802 *pCount =
This->tiff ? pTIFFNumberOfDirectories(
This->tiff) : 0;
805 TRACE(
"(%p) <-- %i\n", iface, *pCount);
816 tiff_decode_info decode_info;
819 TRACE(
"(%p,%u,%p)\n", iface,
index, ppIBitmapFrame);
827 else hr = tiff_get_decode_info(
This->tiff, &decode_info);
836 result->IWICBitmapFrameDecode_iface.lpVtbl = &TiffFrameDecode_Vtbl;
837 result->IWICMetadataBlockReader_iface.lpVtbl = &TiffFrameDecode_BlockVtbl;
840 IWICBitmapDecoder_AddRef(iface);
842 result->decode_info = decode_info;
843 result->cached_tile_x = -1;
847 *ppIBitmapFrame = &
result->IWICBitmapFrameDecode_iface;
851 IWICBitmapFrameDecode_Release(&
result->IWICBitmapFrameDecode_iface);
862static const IWICBitmapDecoderVtbl TiffDecoder_Vtbl = {
863 TiffDecoder_QueryInterface,
866 TiffDecoder_QueryCapability,
867 TiffDecoder_Initialize,
868 TiffDecoder_GetContainerFormat,
869 TiffDecoder_GetDecoderInfo,
870 TiffDecoder_CopyPalette,
871 TiffDecoder_GetMetadataQueryReader,
872 TiffDecoder_GetPreview,
873 TiffDecoder_GetColorContexts,
874 TiffDecoder_GetThumbnail,
875 TiffDecoder_GetFrameCount,
891 *
ppv = &
This->IWICBitmapFrameDecode_iface;
893 else if (
IsEqualIID(&IID_IWICMetadataBlockReader, iid))
895 *
ppv = &
This->IWICMetadataBlockReader_iface;
912 TRACE(
"(%p) refcount=%u\n", iface,
ref);
922 TRACE(
"(%p) refcount=%u\n", iface,
ref);
926 IWICBitmapDecoder_Release(&
This->parent->IWICBitmapDecoder_iface);
939 *puiWidth =
This->decode_info.width;
940 *puiHeight =
This->decode_info.height;
942 TRACE(
"(%p) <-- %ux%u\n", iface, *puiWidth, *puiHeight);
960 double *pDpiX,
double *pDpiY)
964 if (
This->decode_info.xres == 0 ||
This->decode_info.yres == 0)
966 *pDpiX = *pDpiY = 96.0;
970 switch (
This->decode_info.resolution_unit)
973 FIXME(
"unknown resolution unit %i\n",
This->decode_info.resolution_unit);
978 *pDpiX =
This->decode_info.xres;
979 *pDpiY =
This->decode_info.yres;
982 *pDpiX =
This->decode_info.xres * 2.54;
983 *pDpiY =
This->decode_info.yres * 2.54;
988 TRACE(
"(%p) <-- %f,%f unit=%i\n", iface, *pDpiX, *pDpiY,
This->decode_info.resolution_unit);
999 int color_count,
ret,
i;
1001 TRACE(
"(%p,%p)\n", iface, pIPalette);
1003 color_count = 1<<
This->decode_info.bps;
1011 WARN(
"Couldn't read color map\n");
1015 for (
i=0;
i<color_count;
i++)
1017 colors[
i] = 0xff000000 |
1018 ((
red[
i]<<8) & 0xff0000) |
1020 ((
blue[
i]>>8) & 0xff);
1023 return IWICPalette_InitializeCustom(pIPalette, colors, color_count);
1033 ret = pTIFFSetDirectory(
This->parent->tiff,
This->index);
1037 if (
This->decode_info.tiled)
1038 ret = pTIFFReadEncodedTile(
This->parent->tiff, tile_x + tile_y *
This->decode_info.tiles_across,
This->cached_tile,
This->decode_info.tile_size);
1040 ret = pTIFFReadEncodedStrip(
This->parent->tiff, tile_y,
This->cached_tile,
This->decode_info.tile_size);
1046 if (
This->decode_info.source_bpp == 3 &&
This->decode_info.samples == 3 &&
This->decode_info.bpp == 24)
1057 for (
y = 0;
y <
This->decode_info.tile_height;
y++)
1060 dst =
This->cached_tile +
y *
This->decode_info.tile_width * 3;
1062 for (
x = 0;
x <
This->decode_info.tile_width;
x += 8)
1064 dst[2] = (
src[0] & 0x80) ? 0xff : 0;
1065 dst[1] = (
src[0] & 0x40) ? 0xff : 0;
1066 dst[0] = (
src[0] & 0x20) ? 0xff : 0;
1067 if (
x + 1 <
This->decode_info.tile_width)
1069 dst[5] = (
src[0] & 0x10) ? 0xff : 0;
1070 dst[4] = (
src[0] & 0x08) ? 0xff : 0;
1071 dst[3] = (
src[0] & 0x04) ? 0xff : 0;
1073 if (
x + 2 <
This->decode_info.tile_width)
1075 dst[8] = (
src[0] & 0x02) ? 0xff : 0;
1076 dst[7] = (
src[0] & 0x01) ? 0xff : 0;
1077 dst[6] = (
src[1] & 0x80) ? 0xff : 0;
1079 if (
x + 3 <
This->decode_info.tile_width)
1081 dst[11] = (
src[1] & 0x40) ? 0xff : 0;
1082 dst[10] = (
src[1] & 0x20) ? 0xff : 0;
1083 dst[9] = (
src[1] & 0x10) ? 0xff : 0;
1085 if (
x + 4 <
This->decode_info.tile_width)
1087 dst[14] = (
src[1] & 0x08) ? 0xff : 0;
1088 dst[13] = (
src[1] & 0x04) ? 0xff : 0;
1089 dst[12] = (
src[1] & 0x02) ? 0xff : 0;
1091 if (
x + 5 <
This->decode_info.tile_width)
1093 dst[17] = (
src[1] & 0x01) ? 0xff : 0;
1094 dst[16] = (
src[2] & 0x80) ? 0xff : 0;
1095 dst[15] = (
src[2] & 0x40) ? 0xff : 0;
1097 if (
x + 6 <
This->decode_info.tile_width)
1099 dst[20] = (
src[2] & 0x20) ? 0xff : 0;
1100 dst[19] = (
src[2] & 0x10) ? 0xff : 0;
1101 dst[18] = (
src[2] & 0x08) ? 0xff : 0;
1103 if (
x + 7 <
This->decode_info.tile_width)
1105 dst[23] = (
src[2] & 0x04) ? 0xff : 0;
1106 dst[22] = (
src[2] & 0x02) ? 0xff : 0;
1107 dst[21] = (
src[2] & 0x01) ? 0xff : 0;
1117 else if (
This->decode_info.source_bpp == 12 &&
This->decode_info.samples == 3 &&
This->decode_info.bpp == 24)
1128 for (
y = 0;
y <
This->decode_info.tile_height;
y++)
1131 dst =
This->cached_tile +
y *
This->decode_info.tile_width * 3;
1133 for (
x = 0;
x <
This->decode_info.tile_width;
x += 2)
1135 dst[0] = ((
src[1] & 0xf0) >> 4) * 17;
1136 dst[1] = (
src[0] & 0x0f) * 17;
1137 dst[2] = ((
src[0] & 0xf0) >> 4) * 17;
1138 if (
x + 1 <
This->decode_info.tile_width)
1140 dst[5] = (
src[1] & 0x0f) * 17;
1141 dst[4] = ((
src[2] & 0xf0) >> 4) * 17;
1142 dst[3] = (
src[2] & 0x0f) * 17;
1152 else if (
This->decode_info.source_bpp == 4 &&
This->decode_info.samples == 4 &&
This->decode_info.bpp == 32)
1163 for (
y = 0;
y <
This->decode_info.tile_height;
y++)
1166 dst =
This->cached_tile +
y *
This->decode_info.tile_width * 4;
1170 for (
x = 0;
x <
This->decode_info.tile_width;
x += 2)
1172 dst[0] = (
src[0] & 0x20) ? 0xff : 0;
1173 dst[1] = (
src[0] & 0x40) ? 0xff : 0;
1174 dst[2] = (
src[0] & 0x80) ? 0xff : 0;
1175 dst[3] = (
src[0] & 0x10) ? 0xff : 0;
1176 if (
x + 1 <
This->decode_info.tile_width)
1178 dst[4] = (
src[0] & 0x02) ? 0xff : 0;
1179 dst[5] = (
src[0] & 0x04) ? 0xff : 0;
1180 dst[6] = (
src[0] & 0x08) ? 0xff : 0;
1181 dst[7] = (
src[0] & 0x01) ? 0xff : 0;
1191 else if (
This->decode_info.source_bpp == 16 &&
This->decode_info.samples == 4 &&
This->decode_info.bpp == 32)
1197 dst =
This->cached_tile +
This->decode_info.tile_size;
1209 dst[0] = ((
b[1] & 0xf0) >> 4) * 17;
1210 dst[1] = (
b[0] & 0x0f) * 17;
1211 dst[2] = ((
b[0] & 0xf0) >> 4) * 17;
1212 dst[3] = (
b[1] & 0x0f) * 17;
1216 else if (
This->decode_info.source_bpp == 16 &&
This->decode_info.samples == 2 &&
This->decode_info.bpp == 32)
1221 src =
This->cached_tile +
This->decode_info.tile_width *
This->decode_info.tile_height * 2 - 2;
1231 if (
This->decode_info.reverse_bgr)
1233 if (
This->decode_info.bps == 8)
1235 UINT sample_count =
This->decode_info.samples;
1238 This->decode_info.tile_height,
This->decode_info.tile_width * sample_count);
1247 samples_per_row =
This->decode_info.tile_width *
This->decode_info.samples;
1249 switch(
This->decode_info.bps)
1254 sample =
This->cached_tile +
row *
This->decode_info.tile_stride;
1255 for (
i=0;
i<samples_per_row;
i++)
1258 sample[1] = sample[0];
1265 ERR(
"unhandled bps for byte swap %u\n",
This->decode_info.bps);
1270 if (
This->decode_info.invert_grayscale)
1274 if (
This->decode_info.samples != 1)
1276 ERR(
"cannot invert grayscale image with %u samples\n",
This->decode_info.samples);
1280 end =
This->cached_tile+
This->decode_info.tile_size;
1282 for (
byte =
This->cached_tile;
byte !=
end;
byte++)
1286 This->cached_tile_x = tile_x;
1287 This->cached_tile_y = tile_y;
1296 UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y;
1297 UINT tile_x, tile_y;
1310 rect.Width =
This->decode_info.width;
1311 rect.Height =
This->decode_info.height;
1316 if (
prc->X < 0 ||
prc->Y < 0 ||
prc->X+
prc->Width >
This->decode_info.width ||
1317 prc->Y+
prc->Height >
This->decode_info.height)
1321 bytesperrow = ((
This->decode_info.bpp *
prc->Width)+7)/8;
1323 if (cbStride < bytesperrow)
1326 if ((cbStride * (
prc->Height-1)) + bytesperrow > cbBufferSize)
1329 min_tile_x =
prc->X /
This->decode_info.tile_width;
1330 min_tile_y =
prc->Y /
This->decode_info.tile_height;
1331 max_tile_x = (
prc->X+
prc->Width-1) /
This->decode_info.tile_width;
1332 max_tile_y = (
prc->Y+
prc->Height-1) /
This->decode_info.tile_height;
1336 for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++)
1338 for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++)
1340 if (tile_x !=
This->cached_tile_x || tile_y !=
This->cached_tile_y)
1342 hr = TiffFrameDecode_ReadTile(
This, tile_x, tile_y);
1347 if (
prc->X < tile_x *
This->decode_info.tile_width)
1350 rc.
X =
prc->X - tile_x *
This->decode_info.tile_width;
1352 if (
prc->Y < tile_y *
This->decode_info.tile_height)
1355 rc.
Y =
prc->Y - tile_y *
This->decode_info.tile_height;
1357 if (
prc->X+
prc->Width > (tile_x+1) *
This->decode_info.tile_width)
1358 rc.
Width =
This->decode_info.tile_width - rc.
X;
1359 else if (
prc->X < tile_x *
This->decode_info.tile_width)
1360 rc.
Width =
prc->Width +
prc->X - tile_x *
This->decode_info.tile_width;
1364 if (
prc->Y+
prc->Height > (tile_y+1) *
This->decode_info.tile_height)
1366 else if (
prc->Y < tile_y *
This->decode_info.tile_height)
1371 dst_tilepos = pbBuffer + (cbStride * ((rc.
Y + tile_y *
This->decode_info.tile_height) -
prc->Y)) +
1372 ((
This->decode_info.bpp * ((rc.
X + tile_x *
This->decode_info.tile_width) -
prc->X) + 7) / 8);
1375 This->decode_info.tile_width,
This->decode_info.tile_height,
This->decode_info.tile_stride,
1376 &rc, cbStride, cbBufferSize, dst_tilepos);
1398 TRACE(
"(%p,%p)\n", iface, ppIMetadataQueryReader);
1400 if (!ppIMetadataQueryReader)
1414 TRACE(
"(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
1420 if (cCount && ppIColorContexts)
1422 hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts,
profile,
len);
1442 TRACE(
"(%p,%p)\n", iface, ppIThumbnail);
1446 *ppIThumbnail =
NULL;
1450static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl = {
1451 TiffFrameDecode_QueryInterface,
1452 TiffFrameDecode_AddRef,
1453 TiffFrameDecode_Release,
1454 TiffFrameDecode_GetSize,
1455 TiffFrameDecode_GetPixelFormat,
1456 TiffFrameDecode_GetResolution,
1457 TiffFrameDecode_CopyPalette,
1458 TiffFrameDecode_CopyPixels,
1459 TiffFrameDecode_GetMetadataQueryReader,
1460 TiffFrameDecode_GetColorContexts,
1461 TiffFrameDecode_GetThumbnail
1468 return IWICBitmapFrameDecode_QueryInterface(&
This->IWICBitmapFrameDecode_iface, iid,
ppv);
1474 return IWICBitmapFrameDecode_AddRef(&
This->IWICBitmapFrameDecode_iface);
1480 return IWICBitmapFrameDecode_Release(&
This->IWICBitmapFrameDecode_iface);
1490 *
guid = GUID_ContainerFormatTiff;
1517 hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (
void **)&persist);
1520 IWICMetadataReader_Release(metadata_reader);
1526 dir_offset.
QuadPart = pTIFFCurrentDirOffset(
This->parent->tiff);
1527 hr = IStream_Seek(
This->parent->stream, dir_offset, STREAM_SEEK_SET,
NULL);
1531#ifdef WORDS_BIGENDIAN
1537 hr = IWICPersistStream_LoadEx(persist,
This->parent->stream,
NULL, persist_options);
1539 ERR(
"IWICPersistStream_LoadEx error %#x\n",
hr);
1544 IWICPersistStream_Release(persist);
1548 IWICMetadataReader_Release(metadata_reader);
1552 *
reader = metadata_reader;
1571 FIXME(
"(%p,%p): stub\n", iface, enum_metadata);
1575static const IWICMetadataBlockReaderVtbl TiffFrameDecode_BlockVtbl =
1577 TiffFrameDecode_Block_QueryInterface,
1578 TiffFrameDecode_Block_AddRef,
1579 TiffFrameDecode_Block_Release,
1580 TiffFrameDecode_Block_GetContainerFormat,
1581 TiffFrameDecode_Block_GetCount,
1582 TiffFrameDecode_Block_GetReaderByIndex,
1583 TiffFrameDecode_Block_GetEnumerator
1595 if (!load_libtiff())
1604 This->IWICBitmapDecoder_iface.lpVtbl = &TiffDecoder_Vtbl;
1608 This->lock.DebugInfo->Spare[0] = (
DWORD_PTR)(__FILE__
": TiffDecoder.lock");
1612 ret = IWICBitmapDecoder_QueryInterface(&
This->IWICBitmapDecoder_iface, iid,
ppv);
1613 IWICBitmapDecoder_Release(&
This->IWICBitmapDecoder_iface);
1618struct tiff_encode_format {
1625 int extra_sample_type;
1629static const struct tiff_encode_format
formats[] = {
1630 {&GUID_WICPixelFormat24bppBGR, 2, 8, 3, 24, 0, 0, 1},
1631 {&GUID_WICPixelFormat24bppRGB, 2, 8, 3, 24, 0, 0, 0},
1632 {&GUID_WICPixelFormatBlackWhite, 1, 1, 1, 1, 0, 0, 0},
1633 {&GUID_WICPixelFormat4bppGray, 1, 4, 1, 4, 0, 0, 0},
1634 {&GUID_WICPixelFormat8bppGray, 1, 8, 1, 8, 0, 0, 0},
1635 {&GUID_WICPixelFormat32bppBGRA, 2, 8, 4, 32, 1, 2, 1},
1636 {&GUID_WICPixelFormat32bppPBGRA, 2, 8, 4, 32, 1, 1, 1},
1637 {&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0},
1638 {&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0},
1639 {&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0},
1640 {&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0},
1641 {&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0},
1642 {&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0},
1646typedef struct TiffEncoder {
1655 ULONG num_frames_committed;
1663typedef struct TiffFrameEncode {
1671 const struct tiff_encode_format *
format;
1695 *
ppv = &
This->IWICBitmapFrameEncode_iface;
1712 TRACE(
"(%p) refcount=%u\n", iface,
ref);
1722 TRACE(
"(%p) refcount=%u\n", iface,
ref);
1726 IWICBitmapEncoder_Release(&
This->parent->IWICBitmapEncoder_iface);
1737 TRACE(
"(%p,%p)\n", iface, pIEncoderOptions);
1741 if (
This->initialized)
1758 TRACE(
"(%p,%u,%u)\n", iface, uiWidth, uiHeight);
1762 if (!
This->initialized ||
This->info_written)
1768 This->width = uiWidth;
1769 This->height = uiHeight;
1777 double dpiX,
double dpiY)
1780 TRACE(
"(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
1784 if (!
This->initialized ||
This->info_written)
1808 if (!
This->initialized ||
This->info_written)
1814 if (
IsEqualGUID(pPixelFormat, &GUID_WICPixelFormat2bppIndexed))
1815 *pPixelFormat = GUID_WICPixelFormat4bppIndexed;
1836 FIXME(
"(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
1852 if (
This->initialized)
1864 FIXME(
"(%p,%p): stub\n", iface, pIThumbnail);
1872 BYTE *row_data, *swapped_data =
NULL;
1875 TRACE(
"(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
1885 if (lineCount == 0 || lineCount +
This->lines_written >
This->height)
1891 line_size = ((
This->width *
This->format->bpp)+7)/8;
1893 if (
This->format->reverse_bgr)
1903 if (!
This->info_written)
1910 if (
This->format->extra_sample)
1913 extra_samples =
This->format->extra_sample_type;
1921 if (
This->xres != 0.0 &&
This->yres != 0.0)
1928 if (
This->format->bpp <= 8 &&
This->colors && !
IsEqualGUID(
This->format->guid, &GUID_WICPixelFormatBlackWhite))
1933 for (
i = 0;
i <
This->colors;
i++)
1935 red[
i] = (
This->palette[
i] >> 8) & 0xff00;
1946 for (
i=0;
i<lineCount;
i++)
1948 row_data = pbPixels +
i * cbStride;
1950 if (
This->format->reverse_bgr &&
This->format->bps == 8)
1952 memcpy(swapped_data, row_data, line_size);
1953 for (
j=0;
j<line_size;
j +=
This->format->samples)
1956 temp = swapped_data[
j];
1957 swapped_data[
j] = swapped_data[
j+2];
1958 swapped_data[
j+2] =
temp;
1960 row_data = swapped_data;
1963 pTIFFWriteScanline(
This->parent->tiff, (
tdata_t)row_data,
i+
This->lines_written, 0);
1966 This->lines_written += lineCount;
1983 if (!
This->initialized)
2003 TRACE(
"(%p)\n", iface);
2007 if (!
This->info_written ||
This->lines_written !=
This->height ||
This->committed)
2016 This->parent->num_frames_committed++;
2026 FIXME(
"(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
2030static const IWICBitmapFrameEncodeVtbl TiffFrameEncode_Vtbl = {
2031 TiffFrameEncode_QueryInterface,
2032 TiffFrameEncode_AddRef,
2033 TiffFrameEncode_Release,
2034 TiffFrameEncode_Initialize,
2035 TiffFrameEncode_SetSize,
2036 TiffFrameEncode_SetResolution,
2037 TiffFrameEncode_SetPixelFormat,
2038 TiffFrameEncode_SetColorContexts,
2039 TiffFrameEncode_SetPalette,
2040 TiffFrameEncode_SetThumbnail,
2041 TiffFrameEncode_WritePixels,
2042 TiffFrameEncode_WriteSource,
2043 TiffFrameEncode_Commit,
2044 TiffFrameEncode_GetMetadataQueryWriter
2058 *
ppv = &
This->IWICBitmapEncoder_iface;
2075 TRACE(
"(%p) refcount=%u\n", iface,
ref);
2085 TRACE(
"(%p) refcount=%u\n", iface,
ref);
2089 if (
This->tiff) pTIFFClose(
This->tiff);
2090 if (
This->stream) IStream_Release(
This->stream);
2091 This->lock.DebugInfo->Spare[0] = 0;
2106 TRACE(
"(%p,%p,%u)\n", iface, pIStream, cacheOption);
2110 if (
This->initialized ||
This->committed)
2116 tiff = tiff_open_stream(pIStream,
"w");
2125 This->stream = pIStream;
2126 IStream_AddRef(pIStream);
2135 GUID *pguidContainerFormat)
2137 TRACE(
"(%p,%p)\n", iface, pguidContainerFormat);
2139 if (!pguidContainerFormat)
2142 memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff,
sizeof(
GUID));
2158 hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (
void **)
info);
2159 IWICComponentInfo_Release(comp_info);
2167 FIXME(
"(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
2189 TRACE(
"(%p,%p)\n", iface, pIThumbnail);
2195 TRACE(
"(%p,%p)\n", iface, pIPreview);
2204 static const PROPBAG2 opts[2] =
2211 TRACE(
"(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
2215 if (!
This->initialized ||
This->committed)
2219 else if (
This->num_frames !=
This->num_frames_committed)
2221 FIXME(
"New frame created before previous frame was committed\n");
2234 hr = IPropertyBag2_Write(*ppIEncoderOptions, 1, (PROPBAG2 *)opts, &
v);
2238 IPropertyBag2_Release(*ppIEncoderOptions);
2239 *ppIEncoderOptions =
NULL;
2250 result->IWICBitmapFrameEncode_iface.lpVtbl = &TiffFrameEncode_Vtbl;
2261 result->lines_written = 0;
2264 IWICBitmapEncoder_AddRef(iface);
2265 *ppIFrameEncode = &
result->IWICBitmapFrameEncode_iface;
2267 if (
This->num_frames != 0)
2268 pTIFFWriteDirectory(
This->tiff);
2277 IPropertyBag2_Release(*ppIEncoderOptions);
2278 *ppIEncoderOptions =
NULL;
2291 TRACE(
"(%p)\n", iface);
2295 if (!
This->initialized ||
This->committed)
2301 pTIFFClose(
This->tiff);
2302 IStream_Release(
This->stream);
2316 FIXME(
"(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
2320static const IWICBitmapEncoderVtbl TiffEncoder_Vtbl = {
2321 TiffEncoder_QueryInterface,
2323 TiffEncoder_Release,
2324 TiffEncoder_Initialize,
2325 TiffEncoder_GetContainerFormat,
2326 TiffEncoder_GetEncoderInfo,
2327 TiffEncoder_SetColorContexts,
2328 TiffEncoder_SetPalette,
2329 TiffEncoder_SetThumbnail,
2330 TiffEncoder_SetPreview,
2331 TiffEncoder_CreateNewFrame,
2333 TiffEncoder_GetMetadataQueryWriter
2345 if (!load_libtiff())
2354 This->IWICBitmapEncoder_iface.lpVtbl = &TiffEncoder_Vtbl;
2358 This->lock.DebugInfo->Spare[0] = (
DWORD_PTR)(__FILE__
": TiffEncoder.lock");
2361 This->num_frames = 0;
2362 This->num_frames_committed = 0;
2365 ret = IWICBitmapEncoder_QueryInterface(&
This->IWICBitmapEncoder_iface, iid,
ppv);
2366 IWICBitmapEncoder_Release(&
This->IWICBitmapEncoder_iface);
2375 ERR(
"Trying to load TIFF picture, but Wine was compiled without TIFF support.\n");
2381 ERR(
"Trying to save TIFF picture, but Wine was compiled without TIFF support.\n");
#define InterlockedIncrement
#define InterlockedDecrement
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
static BmpDecoder * impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
static BmpDecoder * impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
static BmpFrameEncode * impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
static BmpEncoder * impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size, const struct pixel_format_desc *format) DECLSPEC_HIDDEN
static const struct pixel_format_desc formats[]
#define HeapFree(x, y, z)
static GpStatus get_decoder_info(IStream *stream, const struct image_codec **result)
HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
HRESULT write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, const WICPixelFormatGUID *format, UINT bpp, INT width, INT height)
void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
HRESULT configure_write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, const WICPixelFormatGUID *format, INT width, INT height, double xres, double yres)
HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, IPropertyBag2 **ppPropertyBag2)
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
GLint GLint GLint GLint GLint x
GLint GLint GLint GLint GLint GLint y
GLuint GLuint GLsizei count
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLsizei GLsizei height
GLint GLint GLsizei width
GLboolean GLboolean GLboolean b
GLenum const GLvoid * addr
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
void * wine_dlopen(const char *filename, int flag, char *error, size_t errorsize)
void * wine_dlsym(void *handle, const char *symbol, char *error, size_t errorsize)
#define memcpy(s1, s2, n)
static const WCHAR wszCompressionQuality[]
static const WCHAR wszTiffCompressionMethod[]
#define IsEqualGUID(rguid1, rguid2)
#define IsEqualIID(riid1, riid2)
LIST_ENTRY ProcessLocksList
static void swap_bytes(void *buf, size_t samplesize, size_t samplecount)
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
void TIFFClose(TIFF *tif)
uint64 TIFFCurrentDirOffset(TIFF *tif)
int TIFFSetField(TIFF *tif, uint32 tag,...)
int TIFFGetField(TIFF *tif, uint32 tag,...)
int TIFFSetDirectory(TIFF *tif, uint16 dirn)
uint16 TIFFNumberOfDirectories(TIFF *tif)
int TIFFReadDirectory(TIFF *tif)
int TIFFWriteDirectory(TIFF *tif)
TIFF * TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata, TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, TIFFCloseProc closeproc, TIFFSizeProc sizeproc, TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc)
int TIFFIsByteSwapped(TIFF *tif)
tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32 strip, void *buf, tmsize_t size)
tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32 tile, void *buf, tmsize_t size)
int TIFFWriteScanline(TIFF *tif, void *buf, uint32 row, uint16 sample)
#define TIFFTAG_BITSPERSAMPLE
#define TIFFTAG_RESOLUTIONUNIT
#define TIFFTAG_SAMPLESPERPIXEL
#define TIFFTAG_PHOTOMETRIC
#define TIFFTAG_TILELENGTH
#define TIFFTAG_EXTRASAMPLES
#define TIFFTAG_IMAGEWIDTH
#define TIFFTAG_XRESOLUTION
#define TIFFTAG_ICCPROFILE
#define TIFFTAG_YRESOLUTION
#define TIFFTAG_ROWSPERSTRIP
#define TIFFTAG_TILEWIDTH
#define TIFFTAG_IMAGELENGTH
#define TIFFTAG_PLANARCONFIG
#define CONTAINING_RECORD(address, type, field)
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
void WINAPI VariantInit(VARIANTARG *pVarg)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
WICBitmapEncoderCacheOption
@ WICTiffCompressionDontCare
@ WICDecodeMetadataCacheOnDemand
@ WICBitmapDecoderCapabilityCanDecodeSomeImages
@ WICBitmapDecoderCapabilityCanEnumerateMetadata
@ WICBitmapDecoderCapabilityCanDecodeAllImages
static const char * debug_wic_rect(const WICRect *rect)
@ WICPersistOptionBigEndian
@ WICPersistOptionLittleEndian
@ WICPersistOptionNoCacheStream
#define WINCODEC_ERR_WRONGSTATE
#define WINCODEC_ERR_UNSUPPORTEDOPERATION
#define WINCODEC_ERR_NOTINITIALIZED
#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
#define WINCODEC_ERR_PALETTEUNAVAILABLE
#define WINCODEC_ERR_CODECNOTHUMBNAIL
#define WINCODEC_ERR_FRAMEMISSING