ReactOS 0.4.16-dev-1067-ge98bba2
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 TIFFtiff_open_stream (IStream *stream, const char *mode)
 
static struct tiff_decoderimpl_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_encoderimpl_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 934 of file libtiff.c.

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}
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 malloc
Definition: debug_ros.c:4
GLsizei stride
Definition: glext.h:5848
GLuint buffer
Definition: glext.h:5915
#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:182
static HRESULT tiff_decoder_read_tile(struct tiff_decoder *This, UINT tile_x, UINT tile_y)
Definition: libtiff.c:666
static HRESULT tiff_decoder_select_frame(struct tiff_decoder *This, DWORD frame)
Definition: libtiff.c:610
unsigned int UINT
Definition: ndis.h:50
_Out_ LPRECT prc
Definition: ntgdi.h:1658
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
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 1091 of file libtiff.c.

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}
#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:58
static void tiff_error_handler(const char *module, const char *format, va_list args)
Definition: libtiff.c:51
static const struct decoder_funcs tiff_decoder_vtable
Definition: libtiff.c:1082
TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler)
Definition: tif_error.c:33
TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler handler)
Definition: tif_warning.c:33

Referenced by TiffDecoder_CreateInstance().

◆ tiff_decoder_destroy()

static void CDECL tiff_decoder_destroy ( struct decoder iface)
static

Definition at line 1074 of file libtiff.c.

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}
#define free
Definition: debug_ros.c:5
void TIFFClose(TIFF *tif)
Definition: tif_close.c:122

◆ 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 1015 of file libtiff.c.

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}
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 tag,...)
Definition: tif_dir.c:1232
#define TIFFTAG_ICCPROFILE
Definition: tiff.h:431
#define E_UNEXPECTED
Definition: winerror.h:2456

◆ 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 652 of file libtiff.c.

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}

◆ 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 1042 of file libtiff.c.

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}
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei count
Definition: gl.h:1545
static int blocks
Definition: mkdosfs.c:527
int byte_swapped
Definition: utils.c:251
uint64 TIFFCurrentDirOffset(TIFF *tif)
Definition: tif_dir.c:1666
int TIFFIsByteSwapped(TIFF *tif)
Definition: tif_open.c:639
#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 583 of file libtiff.c.

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}
#define E_FAIL
Definition: ddrawi.h:102
static TIFF * tiff_open_stream(IStream *stream, const char *mode)
Definition: libtiff.c:145
static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
Definition: libtiff.c:187
Definition: parse.h:23
uint16 TIFFNumberOfDirectories(TIFF *tif)
Definition: tif_dir.c:1586
@ 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 666 of file libtiff.c.

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}
#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
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
static void swap_bytes(void *buf, size_t samplesize, size_t samplecount)
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
static UINT width_bytes(UINT width, UINT bpp)
Definition: tiffformat.c:859
tmsize_t tsize_t
Definition: tiffio.h:75
int ret
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 610 of file libtiff.c.

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}
#define E_INVALIDARG
Definition: ddrawi.h:101
GLuint res
Definition: glext.h:9613
int TIFFSetDirectory(TIFF *tif, uint16 dirn)
Definition: tif_dir.c:1617

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 1301 of file libtiff.c.

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}
static struct tiff_encoder * impl_from_encoder(struct encoder *iface)
Definition: libtiff.c:1151

◆ tiff_encoder_commit_frame()

static HRESULT CDECL tiff_encoder_commit_frame ( struct encoder iface)
static

Definition at line 1296 of file libtiff.c.

1297{
1298 return S_OK;
1299}

◆ tiff_encoder_create()

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

Definition at line 1329 of file libtiff.c.

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}
static const struct encoder_funcs tiff_encoder_vtable
Definition: libtiff.c:1319
#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 1194 of file libtiff.c.

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}
unsigned short int uint16_t
Definition: acefiex.h:54
UINT32 uint32_t
Definition: types.h:75
GLclampf green
Definition: gl.h:1740
GLclampf GLclampf blue
Definition: gl.h:1740
static const struct tiff_encode_format formats[]
Definition: libtiff.c:1125
#define red
Definition: linetest.c:67
const GUID * guid
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
WICColor palette[256]
int TIFFSetField(TIFF *tif, uint32 tag,...)
Definition: tif_dir.c:807
int TIFFWriteDirectory(TIFF *tif)
Definition: tif_dirwrite.c:180
#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_EXTRASAMPLES
Definition: tiff.h:303
#define TIFFTAG_IMAGEWIDTH
Definition: tiff.h:154
#define TIFFTAG_XRESOLUTION
Definition: tiff.h:236
#define TIFFTAG_YRESOLUTION
Definition: tiff.h:237
#define TIFFTAG_IMAGELENGTH
Definition: tiff.h:155
#define TIFFTAG_PLANARCONFIG
Definition: tiff.h:238

◆ tiff_encoder_destroy()

static void CDECL tiff_encoder_destroy ( struct encoder iface)
static

Definition at line 1311 of file libtiff.c.

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

◆ 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 1171 of file libtiff.c.

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}
DWORD bpp
Definition: surface.c:185

◆ tiff_encoder_initialize()

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

Definition at line 1156 of file libtiff.c.

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}
TIFF * tiff
Definition: libtiff.c:1144
Definition: tiffiop.h:115

◆ 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 1255 of file libtiff.c.

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}
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 row, uint16 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 51 of file libtiff.c.

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}
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:52
#define ERR_ON(ch)
Definition: debug.h:412
Definition: match.c:390
Definition: format.c:58

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 187 of file libtiff.c.

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}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define E_NOTIMPL
Definition: ddrawi.h:99
GLsizei samples
Definition: glext.h:7006
#define isfinite(x)
Definition: mingw_math.h:91
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
#define max(a, b)
Definition: svc.c:63
#define TIFFTAG_TILELENGTH
Definition: tiff.h:286
#define TIFFTAG_ROWSPERSTRIP
Definition: tiff.h:232
#define TIFFTAG_TILEWIDTH
Definition: tiff.h:285
#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
Definition: winerror.h:3307

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 145 of file libtiff.c.

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}
GLenum mode
Definition: glext.h:6217
static toff_t tiff_stream_size(thandle_t client_data)
Definition: libtiff.c:122
static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
Definition: libtiff.c:88
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 int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
Definition: libtiff.c:134
static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size)
Definition: libtiff.c:140
static int tiff_stream_close(thandle_t client_data)
Definition: libtiff.c:116
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
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 116 of file libtiff.c.

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

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 134 of file libtiff.c.

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

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 66 of file libtiff.c.

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}
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 88 of file libtiff.c.

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}
#define SEEK_END
Definition: cabinet.c:29
GLintptr offset
Definition: glext.h:5920
voidpf uLong int origin
Definition: ioapi.h:144
#define SEEK_SET
Definition: jmemansi.c:26
#define SEEK_CUR
Definition: util.h:63
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 122 of file libtiff.c.

123{
124 IStream *stream = (IStream*)client_data;
126 HRESULT hr;
127
129
130 if (SUCCEEDED(hr)) return size;
131 else return -1;
132}
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 140 of file libtiff.c.

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

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 77 of file libtiff.c.

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}
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 58 of file libtiff.c.

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}
#define WARN_ON(c)
Definition: module.h:257
@ __WINE_DBCL_WARN
Definition: debug.h:53

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 1125 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:1074
static HRESULT CDECL tiff_decoder_get_color_context(struct decoder *iface, UINT frame, UINT num, BYTE **data, DWORD *datasize)
Definition: libtiff.c:1015
static HRESULT CDECL tiff_decoder_get_metadata_blocks(struct decoder *iface, UINT frame, UINT *count, struct decoder_block **blocks)
Definition: libtiff.c:1042
static HRESULT CDECL tiff_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st)
Definition: libtiff.c:583
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 HRESULT CDECL tiff_decoder_get_frame_info(struct decoder *iface, UINT frame, struct decoder_frame *info)
Definition: libtiff.c:652

Definition at line 1082 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:1296
static void CDECL tiff_encoder_destroy(struct encoder *iface)
Definition: libtiff.c:1311
static HRESULT CDECL tiff_encoder_write_lines(struct encoder *iface, BYTE *data, DWORD line_count, DWORD stride)
Definition: libtiff.c:1255
static HRESULT CDECL tiff_encoder_initialize(struct encoder *iface, IStream *stream)
Definition: libtiff.c:1156
static HRESULT CDECL tiff_encoder_create_frame(struct encoder *iface, const struct encoder_frame *frame)
Definition: libtiff.c:1194
static HRESULT CDECL tiff_encoder_commit_file(struct encoder *iface)
Definition: libtiff.c:1301
static HRESULT CDECL tiff_encoder_get_supported_format(struct encoder *iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
Definition: libtiff.c:1171

Definition at line 1319 of file libtiff.c.

Referenced by tiff_encoder_create().