ReactOS 0.4.17-dev-966-gf06eace
libtiff.c File Reference
#include <stdarg.h>
#include <math.h>
#include <sys/types.h>
#include <tiffio.h>
#include "ntstatus.h"
#include "windef.h"
#include "winternl.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
Include dependency graph for libtiff.c:

Go to the source code of this file.

Classes

struct  tiff_decode_info
 
struct  tiff_decoder
 
struct  tiff_encode_format
 
struct  tiff_encoder
 

Macros

#define WIN32_NO_STATUS
 

Typedefs

typedef struct tiff_encoder tiff_encoder
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (wincodecs)
 
 WINE_DECLARE_DEBUG_CHANNEL (tiff)
 
static void tiff_error_handler (const char *module, const char *format, va_list args)
 
static void tiff_warning_handler (const char *module, const char *format, va_list args)
 
static tsize_t tiff_stream_read (thandle_t client_data, tdata_t data, tsize_t size)
 
static tsize_t tiff_stream_write (thandle_t client_data, tdata_t data, tsize_t size)
 
static toff_t tiff_stream_seek (thandle_t client_data, toff_t offset, int whence)
 
static int tiff_stream_close (thandle_t client_data)
 
static toff_t tiff_stream_size (thandle_t client_data)
 
static int tiff_stream_map (thandle_t client_data, tdata_t *addr, toff_t *size)
 
static void tiff_stream_unmap (thandle_t client_data, tdata_t addr, toff_t size)
 
static TIFF * tiff_open_stream (IStream *stream, const char *mode)
 
static struct tiff_decoder * impl_from_decoder (struct decoder *iface)
 
static HRESULT tiff_get_decode_info (TIFF *tiff, tiff_decode_info *decode_info)
 
static HRESULT CDECL tiff_decoder_initialize (struct decoder *iface, IStream *stream, struct decoder_stat *st)
 
static HRESULT tiff_decoder_select_frame (struct tiff_decoder *This, DWORD frame)
 
static HRESULT CDECL tiff_decoder_get_frame_info (struct decoder *iface, UINT frame, struct decoder_frame *info)
 
static HRESULT tiff_decoder_read_tile (struct tiff_decoder *This, UINT tile_x, UINT tile_y)
 
static HRESULT CDECL tiff_decoder_copy_pixels (struct decoder *iface, UINT frame, const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
 
static HRESULT CDECL tiff_decoder_get_color_context (struct decoder *iface, UINT frame, UINT num, BYTE **data, DWORD *datasize)
 
static HRESULT CDECL tiff_decoder_get_metadata_blocks (struct decoder *iface, UINT frame, UINT *count, struct decoder_block **blocks)
 
static void CDECL tiff_decoder_destroy (struct decoder *iface)
 
HRESULT CDECL tiff_decoder_create (struct decoder_info *info, struct decoder **result)
 
static struct tiff_encoder * impl_from_encoder (struct encoder *iface)
 
static HRESULT CDECL tiff_encoder_initialize (struct encoder *iface, IStream *stream)
 
static HRESULT CDECL tiff_encoder_get_supported_format (struct encoder *iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
 
static HRESULT CDECL tiff_encoder_create_frame (struct encoder *iface, const struct encoder_frame *frame)
 
static HRESULT CDECL tiff_encoder_write_lines (struct encoder *iface, BYTE *data, DWORD line_count, DWORD stride)
 
static HRESULT CDECL tiff_encoder_commit_frame (struct encoder *iface)
 
static HRESULT CDECL tiff_encoder_commit_file (struct encoder *iface)
 
static void CDECL tiff_encoder_destroy (struct encoder *iface)
 
HRESULT CDECL tiff_encoder_create (struct encoder_info *info, struct encoder **result)
 

Variables

static const struct decoder_funcs tiff_decoder_vtable
 
static const struct tiff_encode_format formats []
 
static const struct encoder_funcs tiff_encoder_vtable
 

Macro Definition Documentation

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 26 of file libtiff.c.

Typedef Documentation

◆ tiff_encoder

Function Documentation

◆ impl_from_decoder()

static struct tiff_decoder * impl_from_decoder ( struct decoder *  iface)
inlinestatic

◆ impl_from_encoder()

static struct tiff_encoder * impl_from_encoder ( struct encoder *  iface)
inlinestatic

◆ tiff_decoder_copy_pixels()

static HRESULT CDECL tiff_decoder_copy_pixels ( struct decoder *  iface,
UINT  frame,
const WICRect *  prc,
UINT  stride,
UINT  buffersize,
BYTE *  buffer 
)
static

Definition at line 933 of file libtiff.c.

935{
936 struct tiff_decoder *This = impl_from_decoder(iface);
937 HRESULT hr;
938 UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y;
939 UINT tile_x, tile_y;
940 BYTE *dst_tilepos;
941 WICRect rc;
942 tiff_decode_info *info = &This->cached_decode_info;
943
945 if (FAILED(hr))
946 return hr;
947
948 if (!This->cached_tile)
949 {
950 This->cached_tile = malloc(info->tile_size);
951 if (!This->cached_tile)
952 return E_OUTOFMEMORY;
953 }
954
955 min_tile_x = prc->X / info->tile_width;
956 min_tile_y = prc->Y / info->tile_height;
957 max_tile_x = (prc->X+prc->Width-1) / info->tile_width;
958 max_tile_y = (prc->Y+prc->Height-1) / info->tile_height;
959
960 for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++)
961 {
962 for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++)
963 {
964 if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y)
965 {
966 hr = tiff_decoder_read_tile(This, tile_x, tile_y);
967 }
968
969 if (SUCCEEDED(hr))
970 {
971 if (prc->X < tile_x * info->tile_width)
972 rc.X = 0;
973 else
974 rc.X = prc->X - tile_x * info->tile_width;
975
976 if (prc->Y < tile_y * info->tile_height)
977 rc.Y = 0;
978 else
979 rc.Y = prc->Y - tile_y * info->tile_height;
980
981 if (prc->X+prc->Width > (tile_x+1) * info->tile_width)
982 rc.Width = info->tile_width - rc.X;
983 else if (prc->X < tile_x * info->tile_width)
984 rc.Width = prc->Width + prc->X - tile_x * info->tile_width;
985 else
986 rc.Width = prc->Width;
987
988 if (prc->Y+prc->Height > (tile_y+1) * info->tile_height)
989 rc.Height = info->tile_height - rc.Y;
990 else if (prc->Y < tile_y * info->tile_height)
991 rc.Height = prc->Height + prc->Y - tile_y * info->tile_height;
992 else
993 rc.Height = prc->Height;
994
995 dst_tilepos = buffer + (stride * ((rc.Y + tile_y * info->tile_height) - prc->Y)) +
996 ((info->frame.bpp * ((rc.X + tile_x * info->tile_width) - prc->X) + 7) / 8);
997
998 hr = copy_pixels(info->frame.bpp, This->cached_tile,
999 info->tile_width, info->tile_height, info->tile_stride,
1000 &rc, stride, buffersize, dst_tilepos);
1001 }
1002
1003 if (FAILED(hr))
1004 {
1005 TRACE("<-- 0x%lx\n", hr);
1006 return hr;
1007 }
1008 }
1009 }
1010
1011 return S_OK;
1012}
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)
Definition: surface.c:2149
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
GLsizei stride
Definition: glext.h:5848
GLuint buffer
Definition: glext.h:5915
unsigned int UINT
Definition: sysinfo.c:13
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static struct tiff_decoder * impl_from_decoder(struct decoder *iface)
Definition: libtiff.c:181
static HRESULT tiff_decoder_read_tile(struct tiff_decoder *This, UINT tile_x, UINT tile_y)
Definition: libtiff.c:665
static HRESULT tiff_decoder_select_frame(struct tiff_decoder *This, DWORD frame)
Definition: libtiff.c:609
_Out_ LPRECT prc
Definition: ntgdi.h:1658
#define TRACE(s)
Definition: solgame.cpp:4
INT Height
Definition: wincodec.idl:335
INT Width
Definition: wincodec.idl:334
unsigned char BYTE
Definition: xxhash.c:193

◆ tiff_decoder_create()

HRESULT CDECL tiff_decoder_create ( struct decoder_info *  info,
struct decoder **  result 
)

Definition at line 1090 of file libtiff.c.

1091{
1092 struct tiff_decoder *This;
1093
1094 This = malloc(sizeof(*This));
1095 if (!This) return E_OUTOFMEMORY;
1096
1097 This->decoder.vtable = &tiff_decoder_vtable;
1098 This->tiff = NULL;
1099 This->cached_tile = NULL;
1100 This->cached_tile_x = -1;
1101 *result = &This->decoder;
1102
1103 info->container_format = GUID_ContainerFormatTiff;
1104 info->block_format = GUID_ContainerFormatTiff;
1105 info->clsid = CLSID_WICTiffDecoder;
1106
1109 return S_OK;
1110}
#define NULL
Definition: types.h:112
GLuint64EXT * result
Definition: glext.h:11304
static void tiff_warning_handler(const char *module, const char *format, va_list args)
Definition: libtiff.c:57
static void tiff_error_handler(const char *module, const char *format, va_list args)
Definition: libtiff.c:50
static const struct decoder_funcs tiff_decoder_vtable
Definition: libtiff.c:1081
TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler)
Definition: tif_error.c:32
TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler handler)
Definition: tif_warning.c:32

Referenced by TiffDecoder_CreateInstance().

◆ tiff_decoder_destroy()

static void CDECL tiff_decoder_destroy ( struct decoder *  iface)
static

Definition at line 1073 of file libtiff.c.

1074{
1075 struct tiff_decoder *This = impl_from_decoder(iface);
1076 if (This->tiff) TIFFClose(This->tiff);
1077 free(This->cached_tile);
1078 free(This);
1079}
#define free
Definition: debug_ros.c:5
void TIFFClose(TIFF *tif)
Definition: tif_close.c:155

◆ tiff_decoder_get_color_context()

static HRESULT CDECL tiff_decoder_get_color_context ( struct decoder *  iface,
UINT  frame,
UINT  num,
BYTE **  data,
DWORD *  datasize 
)
static

Definition at line 1014 of file libtiff.c.

1016{
1017 struct tiff_decoder *This = impl_from_decoder(iface);
1018 const BYTE *profile;
1019 UINT len;
1020 HRESULT hr;
1021
1023 if (FAILED(hr))
1024 return hr;
1025
1027 {
1028 return E_UNEXPECTED;
1029 }
1030
1031 *datasize = len;
1032 *data = malloc(len);
1033 if (!*data)
1034 return E_OUTOFMEMORY;
1035
1036 memcpy(*data, profile, len);
1037
1038 return S_OK;
1039}
static SIZE_T datasize
Definition: asm.c:30
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLsizei len
Definition: glext.h:6722
#define profile
Definition: kernel32.h:12
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int TIFFGetField(TIFF *tif, uint32_t tag,...)
Definition: tif_dir.c:1582
#define TIFFTAG_ICCPROFILE
Definition: tiff.h:479
#define E_UNEXPECTED
Definition: winerror.h:3528

◆ tiff_decoder_get_frame_info()

static HRESULT CDECL tiff_decoder_get_frame_info ( struct decoder *  iface,
UINT  frame,
struct decoder_frame *  info 
)
static

Definition at line 651 of file libtiff.c.

652{
653 struct tiff_decoder *This = impl_from_decoder(iface);
654 HRESULT hr;
655
657 if (SUCCEEDED(hr))
658 {
659 *info = This->cached_decode_info.frame;
660 }
661
662 return hr;
663}

◆ tiff_decoder_get_metadata_blocks()

static HRESULT CDECL tiff_decoder_get_metadata_blocks ( struct decoder *  iface,
UINT  frame,
UINT *  count,
struct decoder_block **  blocks 
)
static

Definition at line 1041 of file libtiff.c.

1043{
1044 struct tiff_decoder *This = impl_from_decoder(iface);
1045 HRESULT hr;
1046 BOOL byte_swapped;
1047 struct decoder_block result;
1048
1050 if (FAILED(hr))
1051 return hr;
1052
1053 *count = 1;
1054
1055 result.offset = TIFFCurrentDirOffset(This->tiff);
1056 result.length = 0;
1057
1058 byte_swapped = TIFFIsByteSwapped(This->tiff);
1059#ifdef WORDS_BIGENDIAN
1061#else
1063#endif
1065 result.reader_clsid = CLSID_WICIfdMetadataReader;
1066
1067 *blocks = malloc(sizeof(**blocks));
1068 **blocks = result;
1069
1070 return S_OK;
1071}
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei count
Definition: gl.h:1545
static int blocks
Definition: mkdosfs.c:527
uint64_t TIFFCurrentDirOffset(TIFF *tif)
Definition: tif_dir.c:2223
int TIFFIsByteSwapped(TIFF *tif)
Definition: tif_open.c:884
#define DECODER_BLOCK_READER_CLSID
#define DECODER_BLOCK_FULL_STREAM
@ WICPersistOptionBigEndian
Definition: wincodecsdk.idl:25
@ WICPersistOptionLittleEndian
Definition: wincodecsdk.idl:24
@ WICPersistOptionNoCacheStream
Definition: wincodecsdk.idl:27

◆ tiff_decoder_initialize()

static HRESULT CDECL tiff_decoder_initialize ( struct decoder *  iface,
IStream *  stream,
struct decoder_stat *  st 
)
static

Definition at line 582 of file libtiff.c.

583{
584 struct tiff_decoder *This = impl_from_decoder(iface);
585 HRESULT hr;
586
587 This->tiff = tiff_open_stream(stream, "r");
588 if (!This->tiff)
589 return E_FAIL;
590
591 This->frame_count = TIFFNumberOfDirectories(This->tiff);
592 This->cached_frame = 0;
593 hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info);
594 if (FAILED(hr))
595 goto fail;
596
597 st->frame_count = This->frame_count;
601 return S_OK;
602
603fail:
604 TIFFClose(This->tiff);
605 This->tiff = NULL;
606 return hr;
607}
#define E_FAIL
Definition: ddrawi.h:102
static TIFF * tiff_open_stream(IStream *stream, const char *mode)
Definition: libtiff.c:144
static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
Definition: libtiff.c:186
Definition: parse.h:23
tdir_t TIFFNumberOfDirectories(TIFF *tif)
Definition: tif_dir.c:2032
@ WICBitmapDecoderCapabilityCanDecodeSomeImages
Definition: wincodec.idl:51
@ WICBitmapDecoderCapabilityCanEnumerateMetadata
Definition: wincodec.idl:52
@ WICBitmapDecoderCapabilityCanDecodeAllImages
Definition: wincodec.idl:50

◆ tiff_decoder_read_tile()

static HRESULT tiff_decoder_read_tile ( struct tiff_decoder *  This,
UINT  tile_x,
UINT  tile_y 
)
static

Definition at line 665 of file libtiff.c.

666{
667 tsize_t ret;
668 int swap_bytes;
669 tiff_decode_info *info = &This->cached_decode_info;
670
672
673 if (info->tiled)
674 ret = TIFFReadEncodedTile(This->tiff, tile_x + tile_y * info->tiles_across, This->cached_tile, info->tile_size);
675 else
676 ret = TIFFReadEncodedStrip(This->tiff, tile_y, This->cached_tile, info->tile_size);
677
678 if (ret == -1)
679 return E_FAIL;
680
681 /* 3bps RGB */
682 if (info->source_bpp == 3 && info->samples == 3 && info->frame.bpp == 24)
683 {
684 BYTE *srcdata, *src, *dst;
685 DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8;
686
687 count = width_bytes * info->tile_height;
688
689 srcdata = malloc(count);
690 if (!srcdata) return E_OUTOFMEMORY;
691 memcpy(srcdata, This->cached_tile, count);
692
693 for (y = 0; y < info->tile_height; y++)
694 {
695 src = srcdata + y * width_bytes;
696 dst = This->cached_tile + y * info->tile_width * 3;
697
698 for (x = 0; x < info->tile_width; x += 8)
699 {
700 dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
701 dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
702 dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
703 if (x + 1 < info->tile_width)
704 {
705 dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */
706 dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */
707 dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */
708 }
709 if (x + 2 < info->tile_width)
710 {
711 dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */
712 dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */
713 dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */
714 }
715 if (x + 3 < info->tile_width)
716 {
717 dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */
718 dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */
719 dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */
720 }
721 if (x + 4 < info->tile_width)
722 {
723 dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */
724 dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */
725 dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */
726 }
727 if (x + 5 < info->tile_width)
728 {
729 dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */
730 dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */
731 dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */
732 }
733 if (x + 6 < info->tile_width)
734 {
735 dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */
736 dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */
737 dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */
738 }
739 if (x + 7 < info->tile_width)
740 {
741 dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */
742 dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */
743 dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */
744 }
745 src += 3;
746 dst += 24;
747 }
748 }
749
750 free(srcdata);
751 }
752 /* 12bps RGB */
753 else if (info->source_bpp == 12 && info->samples == 3 && info->frame.bpp == 24)
754 {
755 BYTE *srcdata, *src, *dst;
756 DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8;
757
758 count = width_bytes * info->tile_height;
759
760 srcdata = malloc(count);
761 if (!srcdata) return E_OUTOFMEMORY;
762 memcpy(srcdata, This->cached_tile, count);
763
764 for (y = 0; y < info->tile_height; y++)
765 {
766 src = srcdata + y * width_bytes;
767 dst = This->cached_tile + y * info->tile_width * 3;
768
769 for (x = 0; x < info->tile_width; x += 2)
770 {
771 dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
772 dst[1] = (src[0] & 0x0f) * 17; /* G */
773 dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
774 if (x + 1 < info->tile_width)
775 {
776 dst[5] = (src[1] & 0x0f) * 17; /* B */
777 dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */
778 dst[3] = (src[2] & 0x0f) * 17; /* R */
779 }
780 src += 3;
781 dst += 6;
782 }
783 }
784
785 free(srcdata);
786 }
787 /* 4bps RGBA */
788 else if (info->source_bpp == 4 && info->samples == 4 && info->frame.bpp == 32)
789 {
790 BYTE *srcdata, *src, *dst;
791 DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8;
792
793 count = width_bytes * info->tile_height;
794
795 srcdata = malloc(count);
796 if (!srcdata) return E_OUTOFMEMORY;
797 memcpy(srcdata, This->cached_tile, count);
798
799 for (y = 0; y < info->tile_height; y++)
800 {
801 src = srcdata + y * width_bytes;
802 dst = This->cached_tile + y * info->tile_width * 4;
803
804 /* 1 source byte expands to 2 BGRA samples */
805
806 for (x = 0; x < info->tile_width; x += 2)
807 {
808 dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
809 dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
810 dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
811 dst[3] = (src[0] & 0x10) ? 0xff : 0; /* A */
812 if (x + 1 < info->tile_width)
813 {
814 dst[4] = (src[0] & 0x02) ? 0xff : 0; /* B */
815 dst[5] = (src[0] & 0x04) ? 0xff : 0; /* G */
816 dst[6] = (src[0] & 0x08) ? 0xff : 0; /* R */
817 dst[7] = (src[0] & 0x01) ? 0xff : 0; /* A */
818 }
819 src++;
820 dst += 8;
821 }
822 }
823
824 free(srcdata);
825 }
826 /* 16bps RGBA */
827 else if (info->source_bpp == 16 && info->samples == 4 && info->frame.bpp == 32)
828 {
829 BYTE *srcdata, *src, *dst;
830 DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8;
831
832 count = width_bytes * info->tile_height;
833
834 srcdata = malloc(count);
835 if (!srcdata) return E_OUTOFMEMORY;
836 memcpy(srcdata, This->cached_tile, count);
837
838 for (y = 0; y < info->tile_height; y++)
839 {
840 src = srcdata + y * width_bytes;
841 dst = This->cached_tile + y * info->tile_width * 4;
842
843 for (x = 0; x < info->tile_width; x++)
844 {
845 dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
846 dst[1] = (src[0] & 0x0f) * 17; /* G */
847 dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
848 dst[3] = (src[1] & 0x0f) * 17; /* A */
849 src += 2;
850 dst += 4;
851 }
852 }
853
854 free(srcdata);
855 }
856 /* 8bpp grayscale with extra alpha */
857 else if (info->source_bpp == 16 && info->samples == 2 && info->frame.bpp == 32)
858 {
859 BYTE *src;
860 DWORD *dst, count = info->tile_width * info->tile_height;
861
862 src = This->cached_tile + info->tile_width * info->tile_height * 2 - 2;
863 dst = (DWORD *)(This->cached_tile + info->tile_size - 4);
864
865 while (count--)
866 {
867 *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24);
868 src -= 2;
869 }
870 }
871
872 if (info->reverse_bgr)
873 {
874 if (info->bps == 8)
875 {
876 UINT sample_count = info->samples;
877
878 reverse_bgr8(sample_count, This->cached_tile, info->tile_width,
879 info->tile_height, info->tile_width * sample_count);
880 }
881 }
882
883 if (swap_bytes && info->bps > 8)
884 {
885 UINT row, i, samples_per_row;
886 BYTE *sample, temp;
887
888 samples_per_row = info->tile_width * info->samples;
889
890 switch(info->bps)
891 {
892 case 16:
893 for (row=0; row<info->tile_height; row++)
894 {
895 sample = This->cached_tile + row * info->tile_stride;
896 for (i=0; i<samples_per_row; i++)
897 {
898 temp = sample[1];
899 sample[1] = sample[0];
900 sample[0] = temp;
901 sample += 2;
902 }
903 }
904 break;
905 default:
906 ERR("unhandled bps for byte swap %u\n", info->bps);
907 return E_FAIL;
908 }
909 }
910
911 if (info->invert_grayscale)
912 {
913 BYTE *byte, *end;
914
915 if (info->samples != 1)
916 {
917 ERR("cannot invert grayscale image with %u samples\n", info->samples);
918 return E_FAIL;
919 }
920
921 end = This->cached_tile+info->tile_size;
922
923 for (byte = This->cached_tile; byte != end; byte++)
924 *byte = ~(*byte);
925 }
926
927 This->cached_tile_x = tile_x;
928 This->cached_tile_y = tile_y;
929
930 return S_OK;
931}
#define ERR(fmt,...)
Definition: precomp.h:57
#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
return ret
Definition: mutex.c:147
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
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
static calc_node_t temp
Definition: rpn_ieee.c:38
Definition: wave.c:25
static void swap_bytes(void *buf, size_t samplesize, size_t samplecount)
tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, tmsize_t size)
Definition: tif_read.c:534
tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
Definition: tif_read.c:953
static UINT width_bytes(UINT width, UINT bpp)
Definition: tiffformat.c:859
tmsize_t tsize_t
Definition: tiffio.h:80
void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)

Referenced by tiff_decoder_copy_pixels().

◆ tiff_decoder_select_frame()

static HRESULT tiff_decoder_select_frame ( struct tiff_decoder *  This,
DWORD  frame 
)
static

Definition at line 609 of file libtiff.c.

610{
611 HRESULT hr;
612 UINT prev_tile_size;
613 int res;
614
615 if (frame >= This->frame_count)
616 return E_INVALIDARG;
617
618 if (This->cached_frame == frame)
619 return S_OK;
620
621 prev_tile_size = This->cached_tile ? This->cached_decode_info.tile_size : 0;
622
623 res = TIFFSetDirectory(This->tiff, frame);
624 if (!res)
625 return E_INVALIDARG;
626
627 hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info);
628
629 This->cached_tile_x = -1;
630
631 if (SUCCEEDED(hr))
632 {
633 This->cached_frame = frame;
634 if (This->cached_decode_info.tile_size > prev_tile_size)
635 {
636 free(This->cached_tile);
637 This->cached_tile = NULL;
638 }
639 }
640 else
641 {
642 /* Set an invalid value to ensure we'll refresh cached_decode_info before using it. */
643 This->cached_frame = This->frame_count;
644 free(This->cached_tile);
645 This->cached_tile = NULL;
646 }
647
648 return hr;
649}
#define E_INVALIDARG
Definition: ddrawi.h:101
GLuint res
Definition: glext.h:9613
int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
Definition: tif_dir.c:2057

Referenced by tiff_decoder_copy_pixels(), tiff_decoder_get_color_context(), tiff_decoder_get_frame_info(), and tiff_decoder_get_metadata_blocks().

◆ tiff_encoder_commit_file()

static HRESULT CDECL tiff_encoder_commit_file ( struct encoder *  iface)
static

Definition at line 1300 of file libtiff.c.

1301{
1302 struct tiff_encoder* This = impl_from_encoder(iface);
1303
1304 TIFFClose(This->tiff);
1305 This->tiff = NULL;
1306
1307 return S_OK;
1308}
static struct tiff_encoder * impl_from_encoder(struct encoder *iface)
Definition: libtiff.c:1150

◆ tiff_encoder_commit_frame()

static HRESULT CDECL tiff_encoder_commit_frame ( struct encoder *  iface)
static

Definition at line 1295 of file libtiff.c.

1296{
1297 return S_OK;
1298}

◆ tiff_encoder_create()

HRESULT CDECL tiff_encoder_create ( struct encoder_info *  info,
struct encoder **  result 
)

Definition at line 1328 of file libtiff.c.

1329{
1330 struct tiff_encoder *This;
1331
1332 This = malloc(sizeof(*This));
1333 if (!This) return E_OUTOFMEMORY;
1334
1335 This->encoder.vtable = &tiff_encoder_vtable;
1336 This->tiff = NULL;
1337 This->num_frames = 0;
1338
1340 info->container_format = GUID_ContainerFormatTiff;
1341 info->clsid = CLSID_WICTiffEncoder;
1342 info->encoder_options[0] = ENCODER_OPTION_COMPRESSION_METHOD;
1343 info->encoder_options[1] = ENCODER_OPTION_COMPRESSION_QUALITY;
1344 info->encoder_options[2] = ENCODER_OPTION_END;
1345
1346 *result = &This->encoder;
1347
1350 return S_OK;
1351}
static const struct encoder_funcs tiff_encoder_vtable
Definition: libtiff.c:1318
#define ENCODER_FLAGS_MULTI_FRAME
#define ENCODER_FLAGS_SUPPORTS_METADATA
@ ENCODER_OPTION_END
@ ENCODER_OPTION_COMPRESSION_METHOD
@ ENCODER_OPTION_COMPRESSION_QUALITY

Referenced by TiffEncoder_CreateInstance().

◆ tiff_encoder_create_frame()

static HRESULT CDECL tiff_encoder_create_frame ( struct encoder *  iface,
const struct encoder_frame *  frame 
)
static

Definition at line 1193 of file libtiff.c.

1194{
1195 struct tiff_encoder* This = impl_from_encoder(iface);
1196 int i;
1197
1198 if (This->num_frames != 0)
1199 TIFFWriteDirectory(This->tiff);
1200
1201 This->num_frames++;
1202 This->lines_written = 0;
1203 This->encoder_frame = *frame;
1204
1205 for (i=0; formats[i].guid; i++)
1206 {
1207 if (IsEqualGUID(formats[i].guid, &frame->pixel_format))
1208 break;
1209 }
1210
1211 This->format = &formats[i];
1212
1213 TIFFSetField(This->tiff, TIFFTAG_PHOTOMETRIC, (uint16_t)This->format->photometric);
1215 TIFFSetField(This->tiff, TIFFTAG_BITSPERSAMPLE, (uint16_t)This->format->bps);
1216 TIFFSetField(This->tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16_t)This->format->samples);
1217
1218 if (This->format->extra_sample)
1219 {
1220 uint16_t extra_samples;
1221 extra_samples = This->format->extra_sample_type;
1222
1223 TIFFSetField(This->tiff, TIFFTAG_EXTRASAMPLES, (uint16_t)1, &extra_samples);
1224 }
1225
1228
1229 if (frame->dpix != 0.0 && frame->dpiy != 0.0)
1230 {
1231 TIFFSetField(This->tiff, TIFFTAG_RESOLUTIONUNIT, (uint16_t)2); /* Inch */
1232 TIFFSetField(This->tiff, TIFFTAG_XRESOLUTION, (float)frame->dpix);
1233 TIFFSetField(This->tiff, TIFFTAG_YRESOLUTION, (float)frame->dpiy);
1234 }
1235
1236 if (This->format->bpp <= 8 && frame->num_colors && This->format->indexed)
1237 {
1238 uint16_t red[256], green[256], blue[256];
1239 UINT i;
1240
1241 for (i = 0; i < frame->num_colors; i++)
1242 {
1243 red[i] = (frame->palette[i] >> 8) & 0xff00;
1244 green[i] = frame->palette[i] & 0xff00;
1245 blue[i] = (frame->palette[i] << 8) & 0xff00;
1246 }
1247
1249 }
1250
1251 return S_OK;
1252}
UINT32 uint32_t
Definition: types.h:75
GUID guid
Definition: version.c:147
unsigned short uint16_t
Definition: stdint.h:35
GLclampf green
Definition: gl.h:1740
GLclampf GLclampf blue
Definition: gl.h:1740
static const struct tiff_encode_format formats[]
Definition: libtiff.c:1124
#define red
Definition: linetest.c:67
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
WICColor palette[256]
int TIFFSetField(TIFF *tif, uint32_t tag,...)
Definition: tif_dir.c:1146
int TIFFWriteDirectory(TIFF *tif)
Definition: tif_dirwrite.c:238
#define TIFFTAG_BITSPERSAMPLE
Definition: tiff.h:180
#define TIFFTAG_RESOLUTIONUNIT
Definition: tiff.h:287
#define TIFFTAG_SAMPLESPERPIXEL
Definition: tiff.h:257
#define TIFFTAG_COLORMAP
Definition: tiff.h:309
#define TIFFTAG_PHOTOMETRIC
Definition: tiff.h:220
#define TIFFTAG_EXTRASAMPLES
Definition: tiff.h:329
#define TIFFTAG_IMAGEWIDTH
Definition: tiff.h:178
#define TIFFTAG_XRESOLUTION
Definition: tiff.h:262
#define TIFFTAG_YRESOLUTION
Definition: tiff.h:263
#define TIFFTAG_IMAGELENGTH
Definition: tiff.h:179
#define TIFFTAG_PLANARCONFIG
Definition: tiff.h:264

◆ tiff_encoder_destroy()

static void CDECL tiff_encoder_destroy ( struct encoder *  iface)
static

Definition at line 1310 of file libtiff.c.

1311{
1312 struct tiff_encoder *This = impl_from_encoder(iface);
1313
1314 if (This->tiff) TIFFClose(This->tiff);
1315 free(This);
1316}

◆ tiff_encoder_get_supported_format()

static HRESULT CDECL tiff_encoder_get_supported_format ( struct encoder *  iface,
GUID *  pixel_format,
DWORD *  bpp,
BOOL *  indexed 
)
static

Definition at line 1170 of file libtiff.c.

1172{
1173 int i;
1174
1175 if (IsEqualGUID(pixel_format, &GUID_WICPixelFormat2bppIndexed))
1176 *pixel_format = GUID_WICPixelFormat4bppIndexed;
1177
1178 for (i=0; formats[i].guid; i++)
1179 {
1181 break;
1182 }
1183
1184 if (!formats[i].guid) i = 0;
1185
1186 *pixel_format = *formats[i].guid;
1187 *bpp = formats[i].bpp;
1188 *indexed = formats[i].indexed;
1189
1190 return S_OK;
1191}
ULONG bpp[]
Definition: xlate.c:19

◆ tiff_encoder_initialize()

static HRESULT CDECL tiff_encoder_initialize ( struct encoder *  iface,
IStream *  stream 
)
static

Definition at line 1155 of file libtiff.c.

1156{
1157 struct tiff_encoder* This = impl_from_encoder(iface);
1158 TIFF *tiff;
1159
1161
1162 if (!tiff)
1163 return E_FAIL;
1164
1165 This->tiff = tiff;
1166
1167 return S_OK;
1168}
TIFF * tiff
Definition: libtiff.c:1143
Definition: tiffiop.h:113

◆ tiff_encoder_write_lines()

static HRESULT CDECL tiff_encoder_write_lines ( struct encoder *  iface,
BYTE *  data,
DWORD  line_count,
DWORD  stride 
)
static

Definition at line 1254 of file libtiff.c.

1256{
1257 struct tiff_encoder* This = impl_from_encoder(iface);
1258 BYTE *row_data, *swapped_data = NULL;
1259 UINT i, j, line_size;
1260
1261 line_size = ((This->encoder_frame.width * This->format->bpp)+7)/8;
1262
1263 if (This->format->reverse_bgr)
1264 {
1265 swapped_data = malloc(line_size);
1266 if (!swapped_data)
1267 return E_OUTOFMEMORY;
1268 }
1269
1270 for (i=0; i<line_count; i++)
1271 {
1272 row_data = data + i * stride;
1273
1274 if (This->format->reverse_bgr && This->format->bps == 8)
1275 {
1276 memcpy(swapped_data, row_data, line_size);
1277 for (j=0; j<line_size; j += This->format->samples)
1278 {
1279 BYTE temp;
1280 temp = swapped_data[j];
1281 swapped_data[j] = swapped_data[j+2];
1282 swapped_data[j+2] = temp;
1283 }
1284 row_data = swapped_data;
1285 }
1286
1287 TIFFWriteScanline(This->tiff, (tdata_t)row_data, i+This->lines_written, 0);
1288 }
1289
1290 This->lines_written += line_count;
1291
1292 return S_OK;
1293}
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
int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
Definition: tif_write.c:47

◆ tiff_error_handler()

static void tiff_error_handler ( const char *  module,
const char *  format,
va_list  args 
)
static

Definition at line 50 of file libtiff.c.

51{
52 if (!ERR_ON(tiff)) return;
53 if (__wine_dbg_vlog( __WINE_DBCL_ERR, &__wine_dbch_tiff, module, format, args ) != -1)
54 __wine_dbg_output( "\n" );
55}
int(* __wine_dbg_vlog)(unsigned int cls, const char *channel, const char *function, const char *format, va_list args)
@ __WINE_DBCL_ERR
Definition: debug.h:54
const char int int __cdecl __wine_dbg_output(const char *str)
Definition: debug.c:273
#define ERR_ON(ch)
Definition: debug.h:423
Definition: match.c:390

Referenced by tiff_decoder_create(), and tiff_encoder_create().

◆ tiff_get_decode_info()

static HRESULT tiff_get_decode_info ( TIFF *  tiff,
tiff_decode_info *  decode_info 
)
static

Definition at line 186 of file libtiff.c.

187{
188 uint16_t photometric, bps, samples, planar;
189 uint16_t extra_sample_count, extra_sample, *extra_samples;
190 uint16_t *red, *green, *blue;
191 UINT resolution_unit;
192 float xres=0.0, yres=0.0;
193 int ret, i;
194 const BYTE *profile;
195 UINT len;
196
197 decode_info->indexed = 0;
198 decode_info->reverse_bgr = 0;
199 decode_info->invert_grayscale = 0;
200 decode_info->tiled = 0;
201 decode_info->source_bpp = 0;
202
203 ret = TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
204 if (!ret)
205 {
206 WARN("missing PhotometricInterpretation tag\n");
207 return E_FAIL;
208 }
209
211 if (!ret) bps = 1;
212 decode_info->bps = bps;
213
215 if (!ret) samples = 1;
216 decode_info->samples = samples;
217
218 if (samples == 1)
219 planar = 1;
220 else
221 {
223 if (!ret) planar = 1;
224 if (planar != 1)
225 {
226 FIXME("unhandled planar configuration %u\n", planar);
227 return E_FAIL;
228 }
229 }
230 decode_info->planar = planar;
231
232 TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps);
233
234 switch(photometric)
235 {
236 case 0: /* WhiteIsZero */
237 decode_info->invert_grayscale = 1;
238 /* fall through */
239 case 1: /* BlackIsZero */
240 if (samples == 2)
241 {
242 ret = TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
243 if (!ret)
244 {
245 extra_sample_count = 1;
246 extra_sample = 0;
247 extra_samples = &extra_sample;
248 }
249 }
250 else if (samples != 1)
251 {
252 FIXME("unhandled %dbpp sample count %u\n", bps, samples);
253 return E_FAIL;
254 }
255
256 decode_info->frame.bpp = bps * samples;
257 decode_info->source_bpp = decode_info->frame.bpp;
258 switch (bps)
259 {
260 case 1:
261 if (samples != 1)
262 {
263 FIXME("unhandled 1bpp sample count %u\n", samples);
264 return E_FAIL;
265 }
266 decode_info->frame.pixel_format = GUID_WICPixelFormatBlackWhite;
267 break;
268 case 4:
269 if (samples != 1)
270 {
271 FIXME("unhandled 4bpp grayscale sample count %u\n", samples);
272 return E_FAIL;
273 }
274 decode_info->frame.pixel_format = GUID_WICPixelFormat4bppGray;
275 break;
276 case 8:
277 if (samples == 1)
278 decode_info->frame.pixel_format = GUID_WICPixelFormat8bppGray;
279 else
280 {
281 decode_info->frame.bpp = 32;
282
283 switch(extra_samples[0])
284 {
285 case 1: /* Associated (pre-multiplied) alpha data */
286 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA;
287 break;
288 case 0: /* Unspecified data */
289 case 2: /* Unassociated alpha data */
290 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA;
291 break;
292 default:
293 FIXME("unhandled extra sample type %u\n", extra_samples[0]);
294 return E_FAIL;
295 }
296 }
297 break;
298 case 16:
299 if (samples != 1)
300 {
301 FIXME("unhandled 16bpp grayscale sample count %u\n", samples);
303 }
304 decode_info->frame.pixel_format = GUID_WICPixelFormat16bppGray;
305 break;
306 case 32:
307 if (samples != 1)
308 {
309 FIXME("unhandled 32bpp grayscale sample count %u\n", samples);
311 }
312 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppGrayFloat;
313 break;
314 default:
315 WARN("unhandled greyscale bit count %u\n", bps);
317 }
318 break;
319 case 2: /* RGB */
320 if (samples == 4)
321 {
322 ret = TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
323 if (!ret)
324 {
325 extra_sample_count = 1;
326 extra_sample = 0;
327 extra_samples = &extra_sample;
328 }
329 }
330 else if (samples != 3)
331 {
332 FIXME("unhandled RGB sample count %u\n", samples);
333 return E_FAIL;
334 }
335
336 decode_info->frame.bpp = max(bps, 8) * samples;
337 decode_info->source_bpp = bps * samples;
338 switch(bps)
339 {
340 case 1:
341 case 4:
342 case 8:
343 decode_info->reverse_bgr = 1;
344 if (samples == 3)
345 decode_info->frame.pixel_format = GUID_WICPixelFormat24bppBGR;
346 else
347 switch(extra_samples[0])
348 {
349 case 1: /* Associated (pre-multiplied) alpha data */
350 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA;
351 break;
352 case 0: /* Unspecified data */
353 case 2: /* Unassociated alpha data */
354 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA;
355 break;
356 default:
357 FIXME("unhandled extra sample type %i\n", extra_samples[0]);
358 return E_FAIL;
359 }
360 break;
361 case 16:
362 if (samples == 3)
363 decode_info->frame.pixel_format = GUID_WICPixelFormat48bppRGB;
364 else
365 switch(extra_samples[0])
366 {
367 case 1: /* Associated (pre-multiplied) alpha data */
368 decode_info->frame.pixel_format = GUID_WICPixelFormat64bppPRGBA;
369 break;
370 case 0: /* Unspecified data */
371 case 2: /* Unassociated alpha data */
372 decode_info->frame.pixel_format = GUID_WICPixelFormat64bppRGBA;
373 break;
374 default:
375 FIXME("unhandled extra sample type %i\n", extra_samples[0]);
376 return E_FAIL;
377 }
378 break;
379 case 32:
380 if (samples == 3)
381 decode_info->frame.pixel_format = GUID_WICPixelFormat96bppRGBFloat;
382 else
383 switch(extra_samples[0])
384 {
385 case 1: /* Associated (pre-multiplied) alpha data */
386 decode_info->frame.pixel_format = GUID_WICPixelFormat128bppPRGBAFloat;
387 break;
388 case 0: /* Unspecified data */
389 case 2: /* Unassociated alpha data */
390 decode_info->frame.pixel_format = GUID_WICPixelFormat128bppRGBAFloat;
391 break;
392 default:
393 FIXME("unhandled extra sample type %i\n", extra_samples[0]);
394 return E_FAIL;
395 }
396 break;
397 default:
398 WARN("unhandled RGB bit count %u\n", bps);
400 }
401 break;
402 case 3: /* RGB Palette */
403 if (samples != 1)
404 {
405 FIXME("unhandled indexed sample count %u\n", samples);
406 return E_FAIL;
407 }
408
409 decode_info->indexed = 1;
410 decode_info->frame.bpp = bps;
411 switch (bps)
412 {
413 case 1:
414 decode_info->frame.pixel_format = GUID_WICPixelFormat1bppIndexed;
415 break;
416 case 2:
417 decode_info->frame.pixel_format = GUID_WICPixelFormat2bppIndexed;
418 break;
419 case 4:
420 decode_info->frame.pixel_format = GUID_WICPixelFormat4bppIndexed;
421 break;
422 case 8:
423 decode_info->frame.pixel_format = GUID_WICPixelFormat8bppIndexed;
424 break;
425 default:
426 FIXME("unhandled indexed bit count %u\n", bps);
427 return E_NOTIMPL;
428 }
429 break;
430
431 case 5: /* Separated */
432 if (samples != 4)
433 {
434 FIXME("unhandled Separated sample count %u\n", samples);
435 return E_FAIL;
436 }
437
438 decode_info->frame.bpp = bps * samples;
439 switch(bps)
440 {
441 case 8:
442 decode_info->frame.pixel_format = GUID_WICPixelFormat32bppCMYK;
443 break;
444 case 16:
445 decode_info->frame.pixel_format = GUID_WICPixelFormat64bppCMYK;
446 break;
447
448 default:
449 WARN("unhandled Separated bit count %u\n", bps);
451 }
452 break;
453
454 case 4: /* Transparency mask */
455 case 6: /* YCbCr */
456 case 8: /* CIELab */
457 default:
458 FIXME("unhandled PhotometricInterpretation %u\n", photometric);
459 return E_FAIL;
460 }
461
462 ret = TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->frame.width);
463 if (!ret)
464 {
465 WARN("missing image width\n");
466 return E_FAIL;
467 }
468
469 ret = TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->frame.height);
470 if (!ret)
471 {
472 WARN("missing image length\n");
473 return E_FAIL;
474 }
475
476 if ((ret = TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &decode_info->tile_width)))
477 {
478 decode_info->tiled = 1;
479
481 if (!ret)
482 {
483 WARN("missing tile height\n");
484 return E_FAIL;
485 }
486
487 decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
488 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
489 decode_info->tiles_across = (decode_info->frame.width + decode_info->tile_width - 1) / decode_info->tile_width;
490 }
491 else if ((ret = TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height)))
492 {
493 if (decode_info->tile_height > decode_info->frame.height)
494 decode_info->tile_height = decode_info->frame.height;
495 decode_info->tile_width = decode_info->frame.width;
496 decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
497 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
498 }
499 else
500 {
501 /* Some broken TIFF files have a single strip and lack the RowsPerStrip tag */
502 decode_info->tile_height = decode_info->frame.height;
503 decode_info->tile_width = decode_info->frame.width;
504 decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
505 decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
506 }
507
508 resolution_unit = 0;
509 TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resolution_unit);
510
512 if (!ret)
513 {
514 WARN("missing X resolution\n");
515 }
516 /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131)
517 * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */
518 if (!isfinite(xres))
519 {
520 xres = 0.0;
521 }
522
524 if (!ret)
525 {
526 WARN("missing Y resolution\n");
527 }
528 if (!isfinite(yres))
529 {
530 yres = 0.0;
531 }
532
533 if (xres == 0.0 || yres == 0.0)
534 {
535 decode_info->frame.dpix = decode_info->frame.dpiy = 96.0;
536 }
537 else
538 {
539 switch (resolution_unit)
540 {
541 default:
542 FIXME("unknown resolution unit %i\n", resolution_unit);
543 /* fall through */
544 case 0: /* Not set */
545 case 1: /* Relative measurements */
546 case 2: /* Inch */
547 decode_info->frame.dpix = xres;
548 decode_info->frame.dpiy = yres;
549 break;
550 case 3: /* Centimeter */
551 decode_info->frame.dpix = xres * 2.54;
552 decode_info->frame.dpiy = yres * 2.54;
553 break;
554 }
555 }
556
557 if (decode_info->indexed &&
559 {
560 decode_info->frame.num_colors = 1 << decode_info->bps;
561 for (i=0; i<decode_info->frame.num_colors; i++)
562 {
563 decode_info->frame.palette[i] = 0xff000000 |
564 ((red[i]<<8) & 0xff0000) |
565 (green[i] & 0xff00) |
566 ((blue[i]>>8) & 0xff);
567 }
568 }
569 else
570 {
571 decode_info->frame.num_colors = 0;
572 }
573
575 decode_info->frame.num_color_contexts = 1;
576 else
577 decode_info->frame.num_color_contexts = 0;
578
579 return S_OK;
580}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define E_NOTIMPL
Definition: ddrawi.h:99
#define isfinite(x)
Definition: math.h:363
GLsizei samples
Definition: glext.h:7006
UINT tile_stride
Definition: libtiff.c:163
UINT tile_height
Definition: libtiff.c:162
struct decoder_frame frame
Definition: libtiff.c:154
UINT tiles_across
Definition: libtiff.c:166
int invert_grayscale
Definition: libtiff.c:161
#define max(a, b)
Definition: svc.c:63
#define TIFFTAG_TILELENGTH
Definition: tiff.h:312
#define TIFFTAG_ROWSPERSTRIP
Definition: tiff.h:258
#define TIFFTAG_TILEWIDTH
Definition: tiff.h:311
#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
Definition: winerror.h:7318

Referenced by tiff_decoder_initialize(), and tiff_decoder_select_frame().

◆ tiff_open_stream()

static TIFF * tiff_open_stream ( IStream *  stream,
const char *  mode 
)
static

Definition at line 144 of file libtiff.c.

145{
146 stream_seek(stream, 0, STREAM_SEEK_SET, NULL);
147
148 return TIFFClientOpen("<IStream object>", mode, stream, tiff_stream_read,
150 (void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap);
151}
GLenum mode
Definition: glext.h:6217
static toff_t tiff_stream_size(thandle_t client_data)
Definition: libtiff.c:121
static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
Definition: libtiff.c:87
static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size)
Definition: libtiff.c:65
static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size)
Definition: libtiff.c:76
static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
Definition: libtiff.c:133
static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size)
Definition: libtiff.c:139
static int tiff_stream_close(thandle_t client_data)
Definition: libtiff.c:115
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:289
HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position)

Referenced by tiff_decoder_initialize(), and tiff_encoder_initialize().

◆ tiff_stream_close()

static int tiff_stream_close ( thandle_t  client_data)
static

Definition at line 115 of file libtiff.c.

116{
117 /* Caller is responsible for releasing the stream object. */
118 return 0;
119}

Referenced by tiff_open_stream().

◆ tiff_stream_map()

static int tiff_stream_map ( thandle_t  client_data,
tdata_t *  addr,
toff_t *  size 
)
static

Definition at line 133 of file libtiff.c.

134{
135 /* Cannot mmap streams */
136 return 0;
137}

Referenced by tiff_open_stream().

◆ tiff_stream_read()

static tsize_t tiff_stream_read ( thandle_t  client_data,
tdata_t  data,
tsize_t  size 
)
static

Definition at line 65 of file libtiff.c.

66{
67 IStream *stream = (IStream*)client_data;
68 ULONG bytes_read;
69 HRESULT hr;
70
71 hr = stream_read(stream, data, size, &bytes_read);
72 if (FAILED(hr)) bytes_read = 0;
73 return bytes_read;
74}
GLsizeiptr size
Definition: glext.h:5919
static int stream_read
Definition: htmldoc.c:205
uint32_t ULONG
Definition: typedefs.h:59

Referenced by tiff_open_stream().

◆ tiff_stream_seek()

static toff_t tiff_stream_seek ( thandle_t  client_data,
toff_t  offset,
int  whence 
)
static

Definition at line 87 of file libtiff.c.

88{
89 IStream *stream = (IStream*)client_data;
91 ULONGLONG new_position;
92 HRESULT hr;
93
94 switch (whence)
95 {
96 case SEEK_SET:
97 origin = STREAM_SEEK_SET;
98 break;
99 case SEEK_CUR:
100 origin = STREAM_SEEK_CUR;
101 break;
102 case SEEK_END:
103 origin = STREAM_SEEK_END;
104 break;
105 default:
106 ERR("unknown whence value %i\n", whence);
107 return -1;
108 }
109
110 hr = stream_seek(stream, offset, origin, &new_position);
111 if (SUCCEEDED(hr)) return new_position;
112 else return -1;
113}
#define SEEK_END
Definition: cabinet.c:29
#define SEEK_CUR
Definition: stdio.h:44
GLintptr offset
Definition: glext.h:5920
voidpf uLong int origin
Definition: ioapi.h:144
#define SEEK_SET
Definition: jmemansi.c:26
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by tiff_open_stream().

◆ tiff_stream_size()

static toff_t tiff_stream_size ( thandle_t  client_data)
static

Definition at line 121 of file libtiff.c.

122{
123 IStream *stream = (IStream*)client_data;
125 HRESULT hr;
126
128
129 if (SUCCEEDED(hr)) return size;
130 else return -1;
131}
HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size)

Referenced by tiff_open_stream().

◆ tiff_stream_unmap()

static void tiff_stream_unmap ( thandle_t  client_data,
tdata_t  addr,
toff_t  size 
)
static

Definition at line 139 of file libtiff.c.

140{
141 /* No need to ever do this, since we can't map things. */
142}

Referenced by tiff_open_stream().

◆ tiff_stream_write()

static tsize_t tiff_stream_write ( thandle_t  client_data,
tdata_t  data,
tsize_t  size 
)
static

Definition at line 76 of file libtiff.c.

77{
78 IStream *stream = (IStream*)client_data;
79 ULONG bytes_written;
80 HRESULT hr;
81
82 hr = stream_write(stream, data, size, &bytes_written);
83 if (FAILED(hr)) bytes_written = 0;
84 return bytes_written;
85}
HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written)

Referenced by tiff_open_stream().

◆ tiff_warning_handler()

static void tiff_warning_handler ( const char *  module,
const char *  format,
va_list  args 
)
static

Definition at line 57 of file libtiff.c.

58{
59 if (!WARN_ON(tiff)) return;
60 if (__wine_dbg_vlog( __WINE_DBCL_WARN, &__wine_dbch_tiff, module, format, args ) != -1)
61 __wine_dbg_output( "\n" );
62}
#define WARN_ON(c)
Definition: module.h:257
@ __WINE_DBCL_WARN
Definition: debug.h:55

Referenced by tiff_decoder_create(), and tiff_encoder_create().

◆ WINE_DECLARE_DEBUG_CHANNEL()

WINE_DECLARE_DEBUG_CHANNEL ( tiff  )

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( wincodecs  )

Variable Documentation

◆ formats

const struct tiff_encode_format formats[]
static
Initial value:
= {
{&GUID_WICPixelFormat24bppBGR, 2, 8, 3, 24, 0, 0, 1},
{&GUID_WICPixelFormat24bppRGB, 2, 8, 3, 24, 0, 0, 0},
{&GUID_WICPixelFormatBlackWhite, 1, 1, 1, 1, 0, 0, 0},
{&GUID_WICPixelFormat4bppGray, 1, 4, 1, 4, 0, 0, 0},
{&GUID_WICPixelFormat8bppGray, 1, 8, 1, 8, 0, 0, 0},
{&GUID_WICPixelFormat32bppBGRA, 2, 8, 4, 32, 1, 2, 1},
{&GUID_WICPixelFormat32bppPBGRA, 2, 8, 4, 32, 1, 1, 1},
{&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0},
{&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0},
{&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0},
{&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0, 1},
{&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0, 1},
{&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0, 1},
{0}
}

Definition at line 1124 of file libtiff.c.

Referenced by tiff_encoder_create_frame(), and tiff_encoder_get_supported_format().

◆ tiff_decoder_vtable

const struct decoder_funcs tiff_decoder_vtable
static
Initial value:
= {
}
static void CDECL tiff_decoder_destroy(struct decoder *iface)
Definition: libtiff.c:1073
static HRESULT CDECL tiff_decoder_get_color_context(struct decoder *iface, UINT frame, UINT num, BYTE **data, DWORD *datasize)
Definition: libtiff.c:1014
static HRESULT CDECL tiff_decoder_get_metadata_blocks(struct decoder *iface, UINT frame, UINT *count, struct decoder_block **blocks)
Definition: libtiff.c:1041
static HRESULT CDECL tiff_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st)
Definition: libtiff.c:582
static HRESULT CDECL tiff_decoder_copy_pixels(struct decoder *iface, UINT frame, const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
Definition: libtiff.c:933
static HRESULT CDECL tiff_decoder_get_frame_info(struct decoder *iface, UINT frame, struct decoder_frame *info)
Definition: libtiff.c:651

Definition at line 1081 of file libtiff.c.

Referenced by tiff_decoder_create().

◆ tiff_encoder_vtable

const struct encoder_funcs tiff_encoder_vtable
static
Initial value:
= {
}
static HRESULT CDECL tiff_encoder_commit_frame(struct encoder *iface)
Definition: libtiff.c:1295
static void CDECL tiff_encoder_destroy(struct encoder *iface)
Definition: libtiff.c:1310
static HRESULT CDECL tiff_encoder_write_lines(struct encoder *iface, BYTE *data, DWORD line_count, DWORD stride)
Definition: libtiff.c:1254
static HRESULT CDECL tiff_encoder_initialize(struct encoder *iface, IStream *stream)
Definition: libtiff.c:1155
static HRESULT CDECL tiff_encoder_create_frame(struct encoder *iface, const struct encoder_frame *frame)
Definition: libtiff.c:1193
static HRESULT CDECL tiff_encoder_commit_file(struct encoder *iface)
Definition: libtiff.c:1300
static HRESULT CDECL tiff_encoder_get_supported_format(struct encoder *iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
Definition: libtiff.c:1170

Definition at line 1318 of file libtiff.c.

Referenced by tiff_encoder_create().