ReactOS 0.4.16-dev-853-g88d9285
libtiff.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 Vincent Povirk for CodeWeavers
3 * Copyright 2016 Dmitry Timoshkov
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#include <stdarg.h>
21#include <math.h>
22#include <sys/types.h>
23#include <tiffio.h>
24
25#include "ntstatus.h"
26#define WIN32_NO_STATUS
27#include "windef.h"
28#include "winternl.h"
29#include "winbase.h"
30#include "objbase.h"
31
32#include "wincodecs_private.h"
33
34#include "wine/debug.h"
35
37#ifdef __REACTOS__
38#include "wine/library.h"
39extern int isfinite(double x);
40static void tiff_error_handler( const char *module, const char *format, va_list args )
41{
42
43}
44static void tiff_warning_handler( const char *module, const char *format, va_list args )
45{
46
47}
48#else
50
51static void tiff_error_handler( const char *module, const char *format, va_list args )
52{
53 if (!ERR_ON(tiff)) return;
54 if (__wine_dbg_vlog( __WINE_DBCL_ERR, &__wine_dbch_tiff, module, format, args ) != -1)
55 __wine_dbg_output( "\n" );
56}
57
58static void tiff_warning_handler( const char *module, const char *format, va_list args )
59{
60 if (!WARN_ON(tiff)) return;
61 if (__wine_dbg_vlog( __WINE_DBCL_WARN, &__wine_dbch_tiff, module, format, args ) != -1)
62 __wine_dbg_output( "\n" );
63}
64#endif
65
67{
68 IStream *stream = (IStream*)client_data;
69 ULONG bytes_read;
70 HRESULT hr;
71
72 hr = stream_read(stream, data, size, &bytes_read);
73 if (FAILED(hr)) bytes_read = 0;
74 return bytes_read;
75}
76
78{
79 IStream *stream = (IStream*)client_data;
80 ULONG bytes_written;
81 HRESULT hr;
82
83 hr = stream_write(stream, data, size, &bytes_written);
84 if (FAILED(hr)) bytes_written = 0;
85 return bytes_written;
86}
87
88static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
89{
90 IStream *stream = (IStream*)client_data;
92 ULONGLONG new_position;
93 HRESULT hr;
94
95 switch (whence)
96 {
97 case SEEK_SET:
98 origin = STREAM_SEEK_SET;
99 break;
100 case SEEK_CUR:
101 origin = STREAM_SEEK_CUR;
102 break;
103 case SEEK_END:
104 origin = STREAM_SEEK_END;
105 break;
106 default:
107 ERR("unknown whence value %i\n", whence);
108 return -1;
109 }
110
111 hr = stream_seek(stream, offset, origin, &new_position);
112 if (SUCCEEDED(hr)) return new_position;
113 else return -1;
114}
115
116static int tiff_stream_close(thandle_t client_data)
117{
118 /* Caller is responsible for releasing the stream object. */
119 return 0;
120}
121
123{
124 IStream *stream = (IStream*)client_data;
126 HRESULT hr;
127
129
130 if (SUCCEEDED(hr)) return size;
131 else return -1;
132}
133
134static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
135{
136 /* Cannot mmap streams */
137 return 0;
138}
139
141{
142 /* No need to ever do this, since we can't map things. */
143}
144
146{
147 stream_seek(stream, 0, STREAM_SEEK_SET, NULL);
148
149 return TIFFClientOpen("<IStream object>", mode, stream, tiff_stream_read,
151 (void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap);
152}
153
154typedef struct {
155 struct decoder_frame frame;
156 int bps;
163 UINT tile_width, tile_height;
166 int tiled;
169
171{
180};
181
182static inline struct tiff_decoder *impl_from_decoder(struct decoder* iface)
183{
184 return CONTAINING_RECORD(iface, struct tiff_decoder, decoder);
185}
186
188{
189 uint16_t photometric, bps, samples, planar;
190 uint16_t extra_sample_count, extra_sample, *extra_samples;
191 uint16_t *red, *green, *blue;
192 UINT resolution_unit;
193 float xres=0.0, yres=0.0;
194 int ret, i;
195 const BYTE *profile;
196 UINT len;
197
198 decode_info->indexed = 0;
199 decode_info->reverse_bgr = 0;
200 decode_info->invert_grayscale = 0;
201 decode_info->tiled = 0;
202 decode_info->source_bpp = 0;
203
204 ret = TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
205 if (!ret)
206 {
207 WARN("missing PhotometricInterpretation tag\n");
208 return E_FAIL;
209 }
210
212 if (!ret) bps = 1;
213 decode_info->bps = bps;
214
216 if (!ret) samples = 1;
217 decode_info->samples = samples;
218
219 if (samples == 1)
220 planar = 1;
221 else
222 {
224 if (!ret) planar = 1;
225 if (planar != 1)
226 {
227 FIXME("unhandled planar configuration %u\n", planar);
228 return E_FAIL;
229 }
230 }
231 decode_info->planar = planar;
232
233 TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps);
234
235 switch(photometric)
236 {
237 case 0: /* WhiteIsZero */
238 decode_info->invert_grayscale = 1;
239 /* fall through */
240 case 1: /* BlackIsZero */
241 if (samples == 2)
242 {
243 ret = TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
244 if (!ret)
245 {
246 extra_sample_count = 1;
247 extra_sample = 0;
248 extra_samples = &extra_sample;
249 }
250 }
251 else if (samples != 1)
252 {
253 FIXME("unhandled %dbpp sample count %u\n", bps, samples);
254 return E_FAIL;
255 }
256
257 decode_info->frame.bpp = bps * samples;
258 decode_info->source_bpp = decode_info->frame.bpp;
259 switch (bps)
260 {
261 case 1:
262 if (samples != 1)
263 {
264 FIXME("unhandled 1bpp sample count %u\n", samples);
265 return E_FAIL;
266 }
267 decode_info->frame.pixel_format = GUID_WICPixelFormatBlackWhite;
268 break;
269 case 4:
270 if (samples != 1)
271 {
272 FIXME("unhandled 4bpp grayscale sample count %u\n", samples);
273 return E_FAIL;
274 }
275 decode_info->frame.pixel_format = GUID_WICPixelFormat4bppGray;
276 break;
277 case 8:
278 if (samples == 1)
279 decode_info->frame.pixel_format = GUID_WICPixelFormat8bppGray;
280 else
281 {
282 decode_info->frame.bpp = 32;
283
284 switch(extra_samples[0])
285 {
286 case 1: /* Associated (pre-multiplied) alpha data */
287 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA;
288 break;
289 case 0: /* Unspecified data */
290 case 2: /* Unassociated alpha data */
291 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA;
292 break;
293 default:
294 FIXME("unhandled extra sample type %u\n", extra_samples[0]);
295 return E_FAIL;
296 }
297 }
298 break;
299 case 16:
300 if (samples != 1)
301 {
302 FIXME("unhandled 16bpp grayscale sample count %u\n", samples);
304 }
305 decode_info->frame.pixel_format = GUID_WICPixelFormat16bppGray;
306 break;
307 case 32:
308 if (samples != 1)
309 {
310 FIXME("unhandled 32bpp grayscale sample count %u\n", samples);
312 }
313 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppGrayFloat;
314 break;
315 default:
316 WARN("unhandled greyscale bit count %u\n", bps);
318 }
319 break;
320 case 2: /* RGB */
321 if (samples == 4)
322 {
323 ret = TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
324 if (!ret)
325 {
326 extra_sample_count = 1;
327 extra_sample = 0;
328 extra_samples = &extra_sample;
329 }
330 }
331 else if (samples != 3)
332 {
333 FIXME("unhandled RGB sample count %u\n", samples);
334 return E_FAIL;
335 }
336
337 decode_info->frame.bpp = max(bps, 8) * samples;
338 decode_info->source_bpp = bps * samples;
339 switch(bps)
340 {
341 case 1:
342 case 4:
343 case 8:
344 decode_info->reverse_bgr = 1;
345 if (samples == 3)
346 decode_info->frame.pixel_format = GUID_WICPixelFormat24bppBGR;
347 else
348 switch(extra_samples[0])
349 {
350 case 1: /* Associated (pre-multiplied) alpha data */
351 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA;
352 break;
353 case 0: /* Unspecified data */
354 case 2: /* Unassociated alpha data */
355 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA;
356 break;
357 default:
358 FIXME("unhandled extra sample type %i\n", extra_samples[0]);
359 return E_FAIL;
360 }
361 break;
362 case 16:
363 if (samples == 3)
364 decode_info->frame.pixel_format = GUID_WICPixelFormat48bppRGB;
365 else
366 switch(extra_samples[0])
367 {
368 case 1: /* Associated (pre-multiplied) alpha data */
369 decode_info->frame.pixel_format = GUID_WICPixelFormat64bppPRGBA;
370 break;
371 case 0: /* Unspecified data */
372 case 2: /* Unassociated alpha data */
373 decode_info->frame.pixel_format = GUID_WICPixelFormat64bppRGBA;
374 break;
375 default:
376 FIXME("unhandled extra sample type %i\n", extra_samples[0]);
377 return E_FAIL;
378 }
379 break;
380 case 32:
381 if (samples == 3)
382 decode_info->frame.pixel_format = GUID_WICPixelFormat96bppRGBFloat;
383 else
384 switch(extra_samples[0])
385 {
386 case 1: /* Associated (pre-multiplied) alpha data */
387 decode_info->frame.pixel_format = GUID_WICPixelFormat128bppPRGBAFloat;
388 break;
389 case 0: /* Unspecified data */
390 case 2: /* Unassociated alpha data */
391 decode_info->frame.pixel_format = GUID_WICPixelFormat128bppRGBAFloat;
392 break;
393 default:
394 FIXME("unhandled extra sample type %i\n", extra_samples[0]);
395 return E_FAIL;
396 }
397 break;
398 default:
399 WARN("unhandled RGB bit count %u\n", bps);
401 }
402 break;
403 case 3: /* RGB Palette */
404 if (samples != 1)
405 {
406 FIXME("unhandled indexed sample count %u\n", samples);
407 return E_FAIL;
408 }
409
410 decode_info->indexed = 1;
411 decode_info->frame.bpp = bps;
412 switch (bps)
413 {
414 case 1:
415 decode_info->frame.pixel_format = GUID_WICPixelFormat1bppIndexed;
416 break;
417 case 2:
418 decode_info->frame.pixel_format = GUID_WICPixelFormat2bppIndexed;
419 break;
420 case 4:
421 decode_info->frame.pixel_format = GUID_WICPixelFormat4bppIndexed;
422 break;
423 case 8:
424 decode_info->frame.pixel_format = GUID_WICPixelFormat8bppIndexed;
425 break;
426 default:
427 FIXME("unhandled indexed bit count %u\n", bps);
428 return E_NOTIMPL;
429 }
430 break;
431
432 case 5: /* Separated */
433 if (samples != 4)
434 {
435 FIXME("unhandled Separated sample count %u\n", samples);
436 return E_FAIL;
437 }
438
439 decode_info->frame.bpp = bps * samples;
440 switch(bps)
441 {
442 case 8:
443 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppCMYK;
444 break;
445 case 16:
446 decode_info->frame.pixel_format = GUID_WICPixelFormat64bppCMYK;
447 break;
448
449 default:
450 WARN("unhandled Separated bit count %u\n", bps);
452 }
453 break;
454
455 case 4: /* Transparency mask */
456 case 6: /* YCbCr */
457 case 8: /* CIELab */
458 default:
459 FIXME("unhandled PhotometricInterpretation %u\n", photometric);
460 return E_FAIL;
461 }
462
463 ret = TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->frame.width);
464 if (!ret)
465 {
466 WARN("missing image width\n");
467 return E_FAIL;
468 }
469
470 ret = TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->frame.height);
471 if (!ret)
472 {
473 WARN("missing image length\n");
474 return E_FAIL;
475 }
476
477 if ((ret = TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &decode_info->tile_width)))
478 {
479 decode_info->tiled = 1;
480
482 if (!ret)
483 {
484 WARN("missing tile height\n");
485 return E_FAIL;
486 }
487
488 decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
489 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
490 decode_info->tiles_across = (decode_info->frame.width + decode_info->tile_width - 1) / decode_info->tile_width;
491 }
492 else if ((ret = TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height)))
493 {
494 if (decode_info->tile_height > decode_info->frame.height)
495 decode_info->tile_height = decode_info->frame.height;
496 decode_info->tile_width = decode_info->frame.width;
497 decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
498 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
499 }
500 else
501 {
502 /* Some broken TIFF files have a single strip and lack the RowsPerStrip tag */
503 decode_info->tile_height = decode_info->frame.height;
504 decode_info->tile_width = decode_info->frame.width;
505 decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
506 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
507 }
508
509 resolution_unit = 0;
510 TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resolution_unit);
511
513 if (!ret)
514 {
515 WARN("missing X resolution\n");
516 }
517 /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131)
518 * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */
519 if (!isfinite(xres))
520 {
521 xres = 0.0;
522 }
523
525 if (!ret)
526 {
527 WARN("missing Y resolution\n");
528 }
529 if (!isfinite(yres))
530 {
531 yres = 0.0;
532 }
533
534 if (xres == 0.0 || yres == 0.0)
535 {
536 decode_info->frame.dpix = decode_info->frame.dpiy = 96.0;
537 }
538 else
539 {
540 switch (resolution_unit)
541 {
542 default:
543 FIXME("unknown resolution unit %i\n", resolution_unit);
544 /* fall through */
545 case 0: /* Not set */
546 case 1: /* Relative measurements */
547 case 2: /* Inch */
548 decode_info->frame.dpix = xres;
549 decode_info->frame.dpiy = yres;
550 break;
551 case 3: /* Centimeter */
552 decode_info->frame.dpix = xres * 2.54;
553 decode_info->frame.dpiy = yres * 2.54;
554 break;
555 }
556 }
557
558 if (decode_info->indexed &&
560 {
561 decode_info->frame.num_colors = 1 << decode_info->bps;
562 for (i=0; i<decode_info->frame.num_colors; i++)
563 {
564 decode_info->frame.palette[i] = 0xff000000 |
565 ((red[i]<<8) & 0xff0000) |
566 (green[i] & 0xff00) |
567 ((blue[i]>>8) & 0xff);
568 }
569 }
570 else
571 {
572 decode_info->frame.num_colors = 0;
573 }
574
576 decode_info->frame.num_color_contexts = 1;
577 else
578 decode_info->frame.num_color_contexts = 0;
579
580 return S_OK;
581}
582
584{
585 struct tiff_decoder *This = impl_from_decoder(iface);
586 HRESULT hr;
587
588 This->tiff = tiff_open_stream(stream, "r");
589 if (!This->tiff)
590 return E_FAIL;
591
592 This->frame_count = TIFFNumberOfDirectories(This->tiff);
593 This->cached_frame = 0;
594 hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info);
595 if (FAILED(hr))
596 goto fail;
597
598 st->frame_count = This->frame_count;
602 return S_OK;
603
604fail:
605 TIFFClose(This->tiff);
606 This->tiff = NULL;
607 return hr;
608}
609
611{
612 HRESULT hr;
613 UINT prev_tile_size;
614 int res;
615
616 if (frame >= This->frame_count)
617 return E_INVALIDARG;
618
619 if (This->cached_frame == frame)
620 return S_OK;
621
622 prev_tile_size = This->cached_tile ? This->cached_decode_info.tile_size : 0;
623
624 res = TIFFSetDirectory(This->tiff, frame);
625 if (!res)
626 return E_INVALIDARG;
627
628 hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info);
629
630 This->cached_tile_x = -1;
631
632 if (SUCCEEDED(hr))
633 {
634 This->cached_frame = frame;
635 if (This->cached_decode_info.tile_size > prev_tile_size)
636 {
637 free(This->cached_tile);
638 This->cached_tile = NULL;
639 }
640 }
641 else
642 {
643 /* Set an invalid value to ensure we'll refresh cached_decode_info before using it. */
644 This->cached_frame = This->frame_count;
645 free(This->cached_tile);
646 This->cached_tile = NULL;
647 }
648
649 return hr;
650}
651
653{
654 struct tiff_decoder *This = impl_from_decoder(iface);
655 HRESULT hr;
656
658 if (SUCCEEDED(hr))
659 {
660 *info = This->cached_decode_info.frame;
661 }
662
663 return hr;
664}
665
667{
668 tsize_t ret;
669 int swap_bytes;
670 tiff_decode_info *info = &This->cached_decode_info;
671
673
674 if (info->tiled)
675 ret = TIFFReadEncodedTile(This->tiff, tile_x + tile_y * info->tiles_across, This->cached_tile, info->tile_size);
676 else
677 ret = TIFFReadEncodedStrip(This->tiff, tile_y, This->cached_tile, info->tile_size);
678
679 if (ret == -1)
680 return E_FAIL;
681
682 /* 3bps RGB */
683 if (info->source_bpp == 3 && info->samples == 3 && info->frame.bpp == 24)
684 {
685 BYTE *srcdata, *src, *dst;
686 DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8;
687
688 count = width_bytes * info->tile_height;
689
690 srcdata = malloc(count);
691 if (!srcdata) return E_OUTOFMEMORY;
692 memcpy(srcdata, This->cached_tile, count);
693
694 for (y = 0; y < info->tile_height; y++)
695 {
696 src = srcdata + y * width_bytes;
697 dst = This->cached_tile + y * info->tile_width * 3;
698
699 for (x = 0; x < info->tile_width; x += 8)
700 {
701 dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
702 dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
703 dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
704 if (x + 1 < info->tile_width)
705 {
706 dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */
707 dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */
708 dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */
709 }
710 if (x + 2 < info->tile_width)
711 {
712 dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */
713 dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */
714 dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */
715 }
716 if (x + 3 < info->tile_width)
717 {
718 dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */
719 dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */
720 dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */
721 }
722 if (x + 4 < info->tile_width)
723 {
724 dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */
725 dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */
726 dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */
727 }
728 if (x + 5 < info->tile_width)
729 {
730 dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */
731 dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */
732 dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */
733 }
734 if (x + 6 < info->tile_width)
735 {
736 dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */
737 dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */
738 dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */
739 }
740 if (x + 7 < info->tile_width)
741 {
742 dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */
743 dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */
744 dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */
745 }
746 src += 3;
747 dst += 24;
748 }
749 }
750
751 free(srcdata);
752 }
753 /* 12bps RGB */
754 else if (info->source_bpp == 12 && info->samples == 3 && info->frame.bpp == 24)
755 {
756 BYTE *srcdata, *src, *dst;
757 DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8;
758
759 count = width_bytes * info->tile_height;
760
761 srcdata = malloc(count);
762 if (!srcdata) return E_OUTOFMEMORY;
763 memcpy(srcdata, This->cached_tile, count);
764
765 for (y = 0; y < info->tile_height; y++)
766 {
767 src = srcdata + y * width_bytes;
768 dst = This->cached_tile + y * info->tile_width * 3;
769
770 for (x = 0; x < info->tile_width; x += 2)
771 {
772 dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
773 dst[1] = (src[0] & 0x0f) * 17; /* G */
774 dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
775 if (x + 1 < info->tile_width)
776 {
777 dst[5] = (src[1] & 0x0f) * 17; /* B */
778 dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */
779 dst[3] = (src[2] & 0x0f) * 17; /* R */
780 }
781 src += 3;
782 dst += 6;
783 }
784 }
785
786 free(srcdata);
787 }
788 /* 4bps RGBA */
789 else if (info->source_bpp == 4 && info->samples == 4 && info->frame.bpp == 32)
790 {
791 BYTE *srcdata, *src, *dst;
792 DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8;
793
794 count = width_bytes * info->tile_height;
795
796 srcdata = malloc(count);
797 if (!srcdata) return E_OUTOFMEMORY;
798 memcpy(srcdata, This->cached_tile, count);
799
800 for (y = 0; y < info->tile_height; y++)
801 {
802 src = srcdata + y * width_bytes;
803 dst = This->cached_tile + y * info->tile_width * 4;
804
805 /* 1 source byte expands to 2 BGRA samples */
806
807 for (x = 0; x < info->tile_width; x += 2)
808 {
809 dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
810 dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
811 dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
812 dst[3] = (src[0] & 0x10) ? 0xff : 0; /* A */
813 if (x + 1 < info->tile_width)
814 {
815 dst[4] = (src[0] & 0x02) ? 0xff : 0; /* B */
816 dst[5] = (src[0] & 0x04) ? 0xff : 0; /* G */
817 dst[6] = (src[0] & 0x08) ? 0xff : 0; /* R */
818 dst[7] = (src[0] & 0x01) ? 0xff : 0; /* A */
819 }
820 src++;
821 dst += 8;
822 }
823 }
824
825 free(srcdata);
826 }
827 /* 16bps RGBA */
828 else if (info->source_bpp == 16 && info->samples == 4 && info->frame.bpp == 32)
829 {
830 BYTE *srcdata, *src, *dst;
831 DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8;
832
833 count = width_bytes * info->tile_height;
834
835 srcdata = malloc(count);
836 if (!srcdata) return E_OUTOFMEMORY;
837 memcpy(srcdata, This->cached_tile, count);
838
839 for (y = 0; y < info->tile_height; y++)
840 {
841 src = srcdata + y * width_bytes;
842 dst = This->cached_tile + y * info->tile_width * 4;
843
844 for (x = 0; x < info->tile_width; x++)
845 {
846 dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
847 dst[1] = (src[0] & 0x0f) * 17; /* G */
848 dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
849 dst[3] = (src[1] & 0x0f) * 17; /* A */
850 src += 2;
851 dst += 4;
852 }
853 }
854
855 free(srcdata);
856 }
857 /* 8bpp grayscale with extra alpha */
858 else if (info->source_bpp == 16 && info->samples == 2 && info->frame.bpp == 32)
859 {
860 BYTE *src;
861 DWORD *dst, count = info->tile_width * info->tile_height;
862
863 src = This->cached_tile + info->tile_width * info->tile_height * 2 - 2;
864 dst = (DWORD *)(This->cached_tile + info->tile_size - 4);
865
866 while (count--)
867 {
868 *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24);
869 src -= 2;
870 }
871 }
872
873 if (info->reverse_bgr)
874 {
875 if (info->bps == 8)
876 {
877 UINT sample_count = info->samples;
878
879 reverse_bgr8(sample_count, This->cached_tile, info->tile_width,
880 info->tile_height, info->tile_width * sample_count);
881 }
882 }
883
884 if (swap_bytes && info->bps > 8)
885 {
886 UINT row, i, samples_per_row;
887 BYTE *sample, temp;
888
889 samples_per_row = info->tile_width * info->samples;
890
891 switch(info->bps)
892 {
893 case 16:
894 for (row=0; row<info->tile_height; row++)
895 {
896 sample = This->cached_tile + row * info->tile_stride;
897 for (i=0; i<samples_per_row; i++)
898 {
899 temp = sample[1];
900 sample[1] = sample[0];
901 sample[0] = temp;
902 sample += 2;
903 }
904 }
905 break;
906 default:
907 ERR("unhandled bps for byte swap %u\n", info->bps);
908 return E_FAIL;
909 }
910 }
911
912 if (info->invert_grayscale)
913 {
914 BYTE *byte, *end;
915
916 if (info->samples != 1)
917 {
918 ERR("cannot invert grayscale image with %u samples\n", info->samples);
919 return E_FAIL;
920 }
921
922 end = This->cached_tile+info->tile_size;
923
924 for (byte = This->cached_tile; byte != end; byte++)
925 *byte = ~(*byte);
926 }
927
928 This->cached_tile_x = tile_x;
929 This->cached_tile_y = tile_y;
930
931 return S_OK;
932}
933
935 const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
936{
937 struct tiff_decoder *This = impl_from_decoder(iface);
938 HRESULT hr;
939 UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y;
940 UINT tile_x, tile_y;
941 BYTE *dst_tilepos;
942 WICRect rc;
943 tiff_decode_info *info = &This->cached_decode_info;
944
946 if (FAILED(hr))
947 return hr;
948
949 if (!This->cached_tile)
950 {
951 This->cached_tile = malloc(info->tile_size);
952 if (!This->cached_tile)
953 return E_OUTOFMEMORY;
954 }
955
956 min_tile_x = prc->X / info->tile_width;
957 min_tile_y = prc->Y / info->tile_height;
958 max_tile_x = (prc->X+prc->Width-1) / info->tile_width;
959 max_tile_y = (prc->Y+prc->Height-1) / info->tile_height;
960
961 for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++)
962 {
963 for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++)
964 {
965 if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y)
966 {
967 hr = tiff_decoder_read_tile(This, tile_x, tile_y);
968 }
969
970 if (SUCCEEDED(hr))
971 {
972 if (prc->X < tile_x * info->tile_width)
973 rc.X = 0;
974 else
975 rc.X = prc->X - tile_x * info->tile_width;
976
977 if (prc->Y < tile_y * info->tile_height)
978 rc.Y = 0;
979 else
980 rc.Y = prc->Y - tile_y * info->tile_height;
981
982 if (prc->X+prc->Width > (tile_x+1) * info->tile_width)
983 rc.Width = info->tile_width - rc.X;
984 else if (prc->X < tile_x * info->tile_width)
985 rc.Width = prc->Width + prc->X - tile_x * info->tile_width;
986 else
987 rc.Width = prc->Width;
988
989 if (prc->Y+prc->Height > (tile_y+1) * info->tile_height)
990 rc.Height = info->tile_height - rc.Y;
991 else if (prc->Y < tile_y * info->tile_height)
992 rc.Height = prc->Height + prc->Y - tile_y * info->tile_height;
993 else
994 rc.Height = prc->Height;
995
996 dst_tilepos = buffer + (stride * ((rc.Y + tile_y * info->tile_height) - prc->Y)) +
997 ((info->frame.bpp * ((rc.X + tile_x * info->tile_width) - prc->X) + 7) / 8);
998
999 hr = copy_pixels(info->frame.bpp, This->cached_tile,
1000 info->tile_width, info->tile_height, info->tile_stride,
1001 &rc, stride, buffersize, dst_tilepos);
1002 }
1003
1004 if (FAILED(hr))
1005 {
1006 TRACE("<-- 0x%lx\n", hr);
1007 return hr;
1008 }
1009 }
1010 }
1011
1012 return S_OK;
1013}
1014
1016 UINT frame, UINT num, BYTE **data, DWORD *datasize)
1017{
1018 struct tiff_decoder *This = impl_from_decoder(iface);
1019 const BYTE *profile;
1020 UINT len;
1021 HRESULT hr;
1022
1024 if (FAILED(hr))
1025 return hr;
1026
1028 {
1029 return E_UNEXPECTED;
1030 }
1031
1032 *datasize = len;
1033 *data = malloc(len);
1034 if (!*data)
1035 return E_OUTOFMEMORY;
1036
1037 memcpy(*data, profile, len);
1038
1039 return S_OK;
1040}
1041
1043 UINT frame, UINT *count, struct decoder_block **blocks)
1044{
1045 struct tiff_decoder *This = impl_from_decoder(iface);
1046 HRESULT hr;
1048 struct decoder_block result;
1049
1051 if (FAILED(hr))
1052 return hr;
1053
1054 *count = 1;
1055
1056 result.offset = TIFFCurrentDirOffset(This->tiff);
1057 result.length = 0;
1058
1060#ifdef WORDS_BIGENDIAN
1062#else
1064#endif
1066 result.reader_clsid = CLSID_WICIfdMetadataReader;
1067
1068 *blocks = malloc(sizeof(**blocks));
1069 **blocks = result;
1070
1071 return S_OK;
1072}
1073
1074static void CDECL tiff_decoder_destroy(struct decoder* iface)
1075{
1076 struct tiff_decoder *This = impl_from_decoder(iface);
1077 if (This->tiff) TIFFClose(This->tiff);
1078 free(This->cached_tile);
1079 free(This);
1080}
1081
1082static const struct decoder_funcs tiff_decoder_vtable = {
1089};
1090
1092{
1093 struct tiff_decoder *This;
1094
1095 This = malloc(sizeof(*This));
1096 if (!This) return E_OUTOFMEMORY;
1097
1098 This->decoder.vtable = &tiff_decoder_vtable;
1099 This->tiff = NULL;
1100 This->cached_tile = NULL;
1101 This->cached_tile_x = -1;
1102 *result = &This->decoder;
1103
1104 info->container_format = GUID_ContainerFormatTiff;
1105 info->block_format = GUID_ContainerFormatTiff;
1106 info->clsid = CLSID_WICTiffDecoder;
1107
1110 return S_OK;
1111}
1112
1116 int bps;
1118 int bpp;
1123};
1124
1125static const struct tiff_encode_format formats[] = {
1126 {&GUID_WICPixelFormat24bppBGR, 2, 8, 3, 24, 0, 0, 1},
1127 {&GUID_WICPixelFormat24bppRGB, 2, 8, 3, 24, 0, 0, 0},
1128 {&GUID_WICPixelFormatBlackWhite, 1, 1, 1, 1, 0, 0, 0},
1129 {&GUID_WICPixelFormat4bppGray, 1, 4, 1, 4, 0, 0, 0},
1130 {&GUID_WICPixelFormat8bppGray, 1, 8, 1, 8, 0, 0, 0},
1131 {&GUID_WICPixelFormat32bppBGRA, 2, 8, 4, 32, 1, 2, 1},
1132 {&GUID_WICPixelFormat32bppPBGRA, 2, 8, 4, 32, 1, 1, 1},
1133 {&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0},
1134 {&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0},
1135 {&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0},
1136 {&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0, 1},
1137 {&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0, 1},
1138 {&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0, 1},
1139 {0}
1140};
1141
1142typedef struct tiff_encoder {
1150
1151static inline struct tiff_encoder *impl_from_encoder(struct encoder* iface)
1152{
1153 return CONTAINING_RECORD(iface, struct tiff_encoder, encoder);
1154}
1155
1157{
1158 struct tiff_encoder* This = impl_from_encoder(iface);
1159 TIFF *tiff;
1160
1162
1163 if (!tiff)
1164 return E_FAIL;
1165
1166 This->tiff = tiff;
1167
1168 return S_OK;
1169}
1170
1172 GUID *pixel_format, DWORD *bpp, BOOL *indexed)
1173{
1174 int i;
1175
1176 if (IsEqualGUID(pixel_format, &GUID_WICPixelFormat2bppIndexed))
1177 *pixel_format = GUID_WICPixelFormat4bppIndexed;
1178
1179 for (i=0; formats[i].guid; i++)
1180 {
1182 break;
1183 }
1184
1185 if (!formats[i].guid) i = 0;
1186
1187 *pixel_format = *formats[i].guid;
1188 *bpp = formats[i].bpp;
1189 *indexed = formats[i].indexed;
1190
1191 return S_OK;
1192}
1193
1194static HRESULT CDECL tiff_encoder_create_frame(struct encoder* iface, const struct encoder_frame *frame)
1195{
1196 struct tiff_encoder* This = impl_from_encoder(iface);
1197 int i;
1198
1199 if (This->num_frames != 0)
1200 TIFFWriteDirectory(This->tiff);
1201
1202 This->num_frames++;
1203 This->lines_written = 0;
1204 This->encoder_frame = *frame;
1205
1206 for (i=0; formats[i].guid; i++)
1207 {
1208 if (IsEqualGUID(formats[i].guid, &frame->pixel_format))
1209 break;
1210 }
1211
1212 This->format = &formats[i];
1213
1214 TIFFSetField(This->tiff, TIFFTAG_PHOTOMETRIC, (uint16_t)This->format->photometric);
1216 TIFFSetField(This->tiff, TIFFTAG_BITSPERSAMPLE, (uint16_t)This->format->bps);
1217 TIFFSetField(This->tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16_t)This->format->samples);
1218
1219 if (This->format->extra_sample)
1220 {
1221 uint16_t extra_samples;
1222 extra_samples = This->format->extra_sample_type;
1223
1224 TIFFSetField(This->tiff, TIFFTAG_EXTRASAMPLES, (uint16_t)1, &extra_samples);
1225 }
1226
1229
1230 if (frame->dpix != 0.0 && frame->dpiy != 0.0)
1231 {
1232 TIFFSetField(This->tiff, TIFFTAG_RESOLUTIONUNIT, (uint16_t)2); /* Inch */
1233 TIFFSetField(This->tiff, TIFFTAG_XRESOLUTION, (float)frame->dpix);
1234 TIFFSetField(This->tiff, TIFFTAG_YRESOLUTION, (float)frame->dpiy);
1235 }
1236
1237 if (This->format->bpp <= 8 && frame->num_colors && This->format->indexed)
1238 {
1239 uint16_t red[256], green[256], blue[256];
1240 UINT i;
1241
1242 for (i = 0; i < frame->num_colors; i++)
1243 {
1244 red[i] = (frame->palette[i] >> 8) & 0xff00;
1245 green[i] = frame->palette[i] & 0xff00;
1246 blue[i] = (frame->palette[i] << 8) & 0xff00;
1247 }
1248
1250 }
1251
1252 return S_OK;
1253}
1254
1256 BYTE *data, DWORD line_count, DWORD stride)
1257{
1258 struct tiff_encoder* This = impl_from_encoder(iface);
1259 BYTE *row_data, *swapped_data = NULL;
1260 UINT i, j, line_size;
1261
1262 line_size = ((This->encoder_frame.width * This->format->bpp)+7)/8;
1263
1264 if (This->format->reverse_bgr)
1265 {
1266 swapped_data = malloc(line_size);
1267 if (!swapped_data)
1268 return E_OUTOFMEMORY;
1269 }
1270
1271 for (i=0; i<line_count; i++)
1272 {
1273 row_data = data + i * stride;
1274
1275 if (This->format->reverse_bgr && This->format->bps == 8)
1276 {
1277 memcpy(swapped_data, row_data, line_size);
1278 for (j=0; j<line_size; j += This->format->samples)
1279 {
1280 BYTE temp;
1281 temp = swapped_data[j];
1282 swapped_data[j] = swapped_data[j+2];
1283 swapped_data[j+2] = temp;
1284 }
1285 row_data = swapped_data;
1286 }
1287
1288 TIFFWriteScanline(This->tiff, (tdata_t)row_data, i+This->lines_written, 0);
1289 }
1290
1291 This->lines_written += line_count;
1292
1293 return S_OK;
1294}
1295
1297{
1298 return S_OK;
1299}
1300
1302{
1303 struct tiff_encoder* This = impl_from_encoder(iface);
1304
1305 TIFFClose(This->tiff);
1306 This->tiff = NULL;
1307
1308 return S_OK;
1309}
1310
1311static void CDECL tiff_encoder_destroy(struct encoder* iface)
1312{
1313 struct tiff_encoder *This = impl_from_encoder(iface);
1314
1315 if (This->tiff) TIFFClose(This->tiff);
1316 free(This);
1317}
1318
1319static const struct encoder_funcs tiff_encoder_vtable = {
1327};
1328
1330{
1331 struct tiff_encoder *This;
1332
1333 This = malloc(sizeof(*This));
1334 if (!This) return E_OUTOFMEMORY;
1335
1336 This->encoder.vtable = &tiff_encoder_vtable;
1337 This->tiff = NULL;
1338 This->num_frames = 0;
1339
1341 info->container_format = GUID_ContainerFormatTiff;
1342 info->clsid = CLSID_WICTiffEncoder;
1343 info->encoder_options[0] = ENCODER_OPTION_COMPRESSION_METHOD;
1344 info->encoder_options[1] = ENCODER_OPTION_COMPRESSION_QUALITY;
1345 info->encoder_options[2] = ENCODER_OPTION_END;
1346
1347 *result = &This->encoder;
1348
1351 return S_OK;
1352}
unsigned short int uint16_t
Definition: acefiex.h:54
char * va_list
Definition: acmsvcex.h:78
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define SEEK_END
Definition: cabinet.c:29
static SIZE_T datasize
Definition: asm.c:30
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
Definition: surface.c:1700
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
DWORD bpp
Definition: surface.c:185
#define CDECL
Definition: compat.h:29
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
#define byte(x, n)
Definition: tomcrypt.h:118
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
Definition: typeof.h:78
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLclampf green
Definition: gl.h:1740
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLclampf GLclampf blue
Definition: gl.h:1740
GLsizei stride
Definition: glext.h:5848
GLsizei samples
Definition: glext.h:7006
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLenum mode
Definition: glext.h:6217
GLenum GLenum dst
Definition: glext.h:6340
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
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
Definition: glfuncs.h:248
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
Definition: glfuncs.h:250
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
voidpf uLong int origin
Definition: ioapi.h:144
#define SEEK_SET
Definition: jmemansi.c:26
#define profile
Definition: kernel32.h:12
int(* __wine_dbg_vlog)(unsigned int cls, const char *channel, const char *function, const char *format, va_list args)
HRESULT CDECL tiff_decoder_create(struct decoder_info *info, struct decoder **result)
Definition: libtiff.c:1091
static HRESULT CDECL tiff_encoder_commit_frame(struct encoder *iface)
Definition: libtiff.c:1296
static struct tiff_decoder * impl_from_decoder(struct decoder *iface)
Definition: libtiff.c:182
static HRESULT tiff_decoder_read_tile(struct tiff_decoder *This, UINT tile_x, UINT tile_y)
Definition: libtiff.c:666
static TIFF * tiff_open_stream(IStream *stream, const char *mode)
Definition: libtiff.c:145
static void CDECL tiff_encoder_destroy(struct encoder *iface)
Definition: libtiff.c:1311
static void CDECL tiff_decoder_destroy(struct decoder *iface)
Definition: libtiff.c:1074
static HRESULT CDECL tiff_encoder_write_lines(struct encoder *iface, BYTE *data, DWORD line_count, DWORD stride)
Definition: libtiff.c:1255
static void tiff_warning_handler(const char *module, const char *format, va_list args)
Definition: libtiff.c:58
static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
Definition: libtiff.c:187
static toff_t tiff_stream_size(thandle_t client_data)
Definition: libtiff.c:122
static HRESULT CDECL tiff_encoder_initialize(struct encoder *iface, IStream *stream)
Definition: libtiff.c:1156
static HRESULT tiff_decoder_select_frame(struct tiff_decoder *This, DWORD frame)
Definition: libtiff.c:610
static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
Definition: libtiff.c:88
static void tiff_error_handler(const char *module, const char *format, va_list args)
Definition: libtiff.c:51
static HRESULT CDECL tiff_encoder_create_frame(struct encoder *iface, const struct encoder_frame *frame)
Definition: libtiff.c:1194
static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size)
Definition: libtiff.c:66
static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size)
Definition: libtiff.c:77
static HRESULT CDECL tiff_decoder_get_color_context(struct decoder *iface, UINT frame, UINT num, BYTE **data, DWORD *datasize)
Definition: libtiff.c:1015
static const struct encoder_funcs tiff_encoder_vtable
Definition: libtiff.c:1319
static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
Definition: libtiff.c:134
static HRESULT CDECL tiff_decoder_get_metadata_blocks(struct decoder *iface, UINT frame, UINT *count, struct decoder_block **blocks)
Definition: libtiff.c:1042
static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size)
Definition: libtiff.c:140
static HRESULT CDECL tiff_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st)
Definition: libtiff.c:583
static HRESULT CDECL tiff_encoder_commit_file(struct encoder *iface)
Definition: libtiff.c:1301
HRESULT CDECL tiff_encoder_create(struct encoder_info *info, struct encoder **result)
Definition: libtiff.c:1329
static const struct tiff_encode_format formats[]
Definition: libtiff.c:1125
static HRESULT CDECL tiff_decoder_copy_pixels(struct decoder *iface, UINT frame, const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
Definition: libtiff.c:934
static int tiff_stream_close(thandle_t client_data)
Definition: libtiff.c:116
static HRESULT CDECL tiff_decoder_get_frame_info(struct decoder *iface, UINT frame, struct decoder_frame *info)
Definition: libtiff.c:652
static const struct decoder_funcs tiff_decoder_vtable
Definition: libtiff.c:1082
static HRESULT CDECL tiff_encoder_get_supported_format(struct encoder *iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
Definition: libtiff.c:1171
static struct tiff_encoder * impl_from_encoder(struct encoder *iface)
Definition: libtiff.c:1151
#define red
Definition: linetest.c:67
const GUID * guid
#define isfinite(x)
Definition: mingw_math.h:91
static int blocks
Definition: mkdosfs.c:527
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define WARN_ON(c)
Definition: module.h:257
#define SEEK_CUR
Definition: util.h:63
static int stream_read
Definition: htmldoc.c:205
unsigned int UINT
Definition: ndis.h:50
_Out_ LPRECT prc
Definition: ntgdi.h:1658
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
static calc_node_t temp
Definition: rpn_ieee.c:38
@ __WINE_DBCL_ERR
Definition: debug.h:52
@ __WINE_DBCL_WARN
Definition: debug.h:53
#define ERR_ON(ch)
Definition: debug.h:412
int byte_swapped
Definition: utils.c:251
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
INT Height
Definition: wincodec.idl:335
INT Width
Definition: wincodec.idl:334
Definition: match.c:390
WICColor palette[256]
Definition: format.c:58
Definition: parse.h:23
UINT tile_stride
Definition: libtiff.c:164
UINT tile_height
Definition: libtiff.c:163
struct decoder_frame frame
Definition: libtiff.c:155
UINT tiles_across
Definition: libtiff.c:167
int invert_grayscale
Definition: libtiff.c:162
tiff_decode_info cached_decode_info
Definition: libtiff.c:177
DWORD frame_count
Definition: libtiff.c:175
BYTE * cached_tile
Definition: libtiff.c:179
INT cached_tile_y
Definition: libtiff.c:178
TIFF * tiff
Definition: libtiff.c:174
DWORD cached_frame
Definition: libtiff.c:176
IStream * stream
Definition: libtiff.c:173
INT cached_tile_x
Definition: libtiff.c:178
const WICPixelFormatGUID * guid
Definition: libtiff.c:1114
TIFF * tiff
Definition: libtiff.c:1144
DWORD lines_written
Definition: libtiff.c:1148
DWORD num_frames
Definition: libtiff.c:1147
const struct tiff_encode_format * format
Definition: libtiff.c:1145
Definition: tiffiop.h:115
#define max(a, b)
Definition: svc.c:63
static void swap_bytes(void *buf, size_t samplesize, size_t samplecount)
void TIFFClose(TIFF *tif)
Definition: tif_close.c:122
uint64 TIFFCurrentDirOffset(TIFF *tif)
Definition: tif_dir.c:1666
int TIFFSetField(TIFF *tif, uint32 tag,...)
Definition: tif_dir.c:807
int TIFFGetField(TIFF *tif, uint32 tag,...)
Definition: tif_dir.c:1232
int TIFFSetDirectory(TIFF *tif, uint16 dirn)
Definition: tif_dir.c:1617
uint16 TIFFNumberOfDirectories(TIFF *tif)
Definition: tif_dir.c:1586
int TIFFWriteDirectory(TIFF *tif)
Definition: tif_dirwrite.c:180
TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler)
Definition: tif_error.c:33
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)
Definition: tif_open.c:71
int TIFFIsByteSwapped(TIFF *tif)
Definition: tif_open.c:639
tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32 strip, void *buf, tmsize_t size)
Definition: tif_read.c:527
tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32 tile, void *buf, tmsize_t size)
Definition: tif_read.c:978
TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler handler)
Definition: tif_warning.c:33
int TIFFWriteScanline(TIFF *tif, void *buf, uint32 row, uint16 sample)
Definition: tif_write.c:47
#define TIFFTAG_BITSPERSAMPLE
Definition: tiff.h:156
#define TIFFTAG_RESOLUTIONUNIT
Definition: tiff.h:261
#define TIFFTAG_SAMPLESPERPIXEL
Definition: tiff.h:231
#define TIFFTAG_COLORMAP
Definition: tiff.h:283
#define TIFFTAG_PHOTOMETRIC
Definition: tiff.h:194
#define TIFFTAG_TILELENGTH
Definition: tiff.h:286
#define TIFFTAG_EXTRASAMPLES
Definition: tiff.h:303
#define TIFFTAG_IMAGEWIDTH
Definition: tiff.h:154
#define TIFFTAG_XRESOLUTION
Definition: tiff.h:236
#define TIFFTAG_ICCPROFILE
Definition: tiff.h:431
#define TIFFTAG_YRESOLUTION
Definition: tiff.h:237
#define TIFFTAG_ROWSPERSTRIP
Definition: tiff.h:232
#define TIFFTAG_TILEWIDTH
Definition: tiff.h:285
#define TIFFTAG_IMAGELENGTH
Definition: tiff.h:155
#define TIFFTAG_PLANARCONFIG
Definition: tiff.h:238
static UINT width_bytes(UINT width, UINT bpp)
Definition: tiffformat.c:859
uint64 toff_t
Definition: tiffio.h:66
tmsize_t tsize_t
Definition: tiffio.h:75
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
int ret
@ WICBitmapDecoderCapabilityCanDecodeSomeImages
Definition: wincodec.idl:51
@ WICBitmapDecoderCapabilityCanEnumerateMetadata
Definition: wincodec.idl:52
@ WICBitmapDecoderCapabilityCanDecodeAllImages
Definition: wincodec.idl:50
HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written)
HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size)
HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position)
void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
#define DECODER_BLOCK_READER_CLSID
#define DECODER_BLOCK_FULL_STREAM
#define ENCODER_FLAGS_MULTI_FRAME
#define ENCODER_FLAGS_SUPPORTS_METADATA
@ ENCODER_OPTION_END
@ ENCODER_OPTION_COMPRESSION_METHOD
@ ENCODER_OPTION_COMPRESSION_QUALITY
@ WICPersistOptionBigEndian
Definition: wincodecsdk.idl:25
@ WICPersistOptionLittleEndian
Definition: wincodecsdk.idl:24
@ WICPersistOptionNoCacheStream
Definition: wincodecsdk.idl:27
#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
Definition: winerror.h:3307
#define E_UNEXPECTED
Definition: winerror.h:2456
unsigned char BYTE
Definition: xxhash.c:193