1 #ifndef _IMAGE_READER_H_
2 #define _IMAGE_READER_H_
3 
4 #include "png.h"
5 
6 extern "C" {
7 #include "jpeglib.h"
8 #include "jerror.h"
9 #include "jmorecfg.h"
10 }
11 
12 
13 // mode flags kept in internal variable mMode
14 #define IMAGE_READER_MODE_DITHER        0x01
15 
16 #define DITHER_SPECKLE_LIMIT 400
17 #define FS_SCALE 1024
18 
19 enum IMAGE_TYPES {
20     IMAGE_TYPE_UNKNOWN = 0,
21     IMAGE_TYPE_PNG,
22     IMAGE_TYPE_JPG,
23     IMAGE_TYPE_GIF,
24     IMAGE_TYPE_BMP,
25     // KGM: Add support for tif, others?
26 };
27 
28 class Pixel  {
29     public:
Pixel(void)30         Pixel(void)
31         {
32             Red = Green = Blue = Alpha = 0;
33         }
34 
35         Pixel(int Red, int Green, int Blue);
36         Pixel(GX_COLOR color);
37 
38         BOOL operator == (const Pixel &Pix) const;
39         BOOL operator != (const Pixel &Pix) const;
40 
41         int Red;
42         int Green;
43         int Blue;
44         int Alpha;
45 };
46 
47 typedef struct  {
48     int Width;
49     int Height;
50     int BitsPerPix;
51 } image_info;
52 
53 
54 class image_reader
55 {
56     public:
57         image_reader();
58         virtual ~image_reader();
59 
60         void DestroyImage();
CheckImageHasAlphaChannel(CString & path)61         virtual BOOL CheckImageHasAlphaChannel(CString &path) {return FALSE;}
62         virtual BOOL ReadImage(CString &path, int frame_id = -1) = 0;
63         virtual BOOL ReadImage(unsigned char *data, int data_size) = 0;
64 
65         BOOL FinalizeImage(int width, int height);
66         BOOL RleEncode(GX_PIXELMAP *pMap, BOOL targa_format = FALSE);
67 
68         GX_PIXELMAP *ResizeImage(GX_PIXELMAP *src, int dest_width, int dest_height);
69 
70         GX_PIXELMAP *GetPixelmap(int frame_id = 0);
71         virtual INT GetDelayTime(int frame_id = 0) = 0;
72         static INT GetFrameCount(CString& path);
73 
GetPalette()74         GX_COLOR *GetPalette() {return mpPalette;}
GetPalSize()75         int       GetPalSize() {return mPalSize;}
76 
77         static int GetImageType(CString &path);
78         static int GetImageType(unsigned char *data, int data_size);
79         static image_reader *CreateProperReader(int image_type);
80         static image_reader *CreateProperReader(CString &path);
81         static image_reader *CreateProperReader(unsigned char *data, int data_size);
82 
83         void SetSaveAlphaVal(BOOL Save);
84         void DoCompress(BOOL docompress);
85         void SetDither(BOOL bDither);
86         BOOL SetOutputColorFormat(int output_format, int display_color_format);
87         void SetPalette(GX_COLOR *pal, int size, int fixed);
GetDisplayFormat()88         INT GetDisplayFormat() { return mDisplayFormat; }
89 
90         //void SetDisplayFormat(UINT Format);
91         static int GetNearestPaletteColor(Pixel want_color, GX_COLOR *palette, int palsize);
92         static void ConvertRGBToGray(GX_COLOR rgb_val, GX_UBYTE *gray_val);
93         static void ConvertRGBToGray(GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue, GX_UBYTE *gray_val);
94 
95         const GX_UBYTE *mpGetData;
96 
97     protected:
98 
99         virtual UCHAR *GetInputDataPtr(int row) = 0;
100 
101         void ComputeGrayThreshod(int width, int height);
102         void ColorSpaceConvert(int width, int height, GX_PIXELMAP *map);
103         void ColorSpaceConvertRow(int Width);
104 
105         int CountDuplicates(int Index, int Width);
106         USHORT WriteRleCount(USHORT count, UCHAR *pPutCount, BOOL bRaw);
107         GX_UBYTE *GetCountLocation();
108         void RleEncodeRow(int Width);
109 
110         BOOL InitDither(int cols);
111         void DitherOneRow(int Width);
112         void DitherCleanup(void);
113 
114         void SetDefaultPixelReader(int input_bits_per_pix);
115         int CalculateOutputStride(int ImgWidth);
116 
117         // Raw Data readers
118         // This is a group of functions that read pixel data from the input
119         // stream. Most of these input-data reader functions are provided
120         // by the format-specific sub-class, but we provide the most simple
121         // and common versions as part of the base class so that they can be
122         // re-used by multiple decoders
123 
124         static void ReadPixel16(image_reader *reader, int Index, Pixel *pPut);
125         static void ReadPixel24(image_reader *reader, int Index, Pixel *pPut);
126         static void ReadPixel32(image_reader *reader, int Index, Pixel *pPut);
127 
128         // Pixel data writers-
129         // A group of functions for writing Pixelmap output data in the requested
130         // format. Only supporting 16, 24, and 32 bit formats at first.
131         // FIXME: Need to add 1bpp to 8bpp formats.
132 
133         static Pixel WritePixelMono(image_reader *reader, Pixel pPixel);
134         static Pixel WritePixelMono_transparent(image_reader *reader, Pixel pPixel);
135         static Pixel WritePixel4bppgrayscale_transparent(image_reader *reader, Pixel pPixel);
136         static Pixel WritePixel4bppgrayscale(image_reader *reader, Pixel pPixel);
137         static Pixel WritePixel8bppPalette(image_reader *reader, Pixel pPixel);
138         static Pixel WritePixel8bppAlpha(image_reader *reader, Pixel pPixel);
139         static Pixel WritePixel8Bit_332_RGB(image_reader *reader, Pixel pPixel);
140         static Pixel WritePixel8Bit_332_Alpha(image_reader *reader, Pixel pPixel);
141         static Pixel WritePixel16Bit_555(image_reader *reader, Pixel pPixel);
142         static Pixel WritePixel16Bit_555_BGR(image_reader *reader, Pixel pPixel);
143         static Pixel WritePixel16Bit_555_Alpha(image_reader *reader, Pixel pPixel);
144         static Pixel WritePixel16Bit_565_Alpha(image_reader *reader, Pixel pPixel);
145         static Pixel WritePixel16Bit_565_BGR(image_reader *reader, Pixel pPixel);
146         static Pixel WritePixel16Bit_565_BGR_Alpha(image_reader *reader, Pixel pPixel);
147         static Pixel WritePixel16Bit_565_RGB(image_reader *reader, Pixel pPixel);
148         static Pixel WritePixel16Bit_4444_ARGB(image_reader *reader, Pixel pPixel);
149         static Pixel WritePixel16Bit_4444_ARGB_Alpha(image_reader *reader, Pixel pPixel);
150         static Pixel WritePixel16Bit_4444_BGRA(image_reader *reader, Pixel pPixel);
151         static Pixel WritePixel24Bit_BGRPacked(image_reader *reader, Pixel pPixel);
152         static Pixel WritePixel24Bit_RGBPacked(image_reader *reader, Pixel pPixel);
153         static Pixel WritePixel32Bit_ARGB(image_reader *reader, Pixel pPixel);
154         static Pixel WritePixel32Bit_565_RGB_Alpha(image_reader *reader, Pixel pPixel);
155         static Pixel WritePixel32Bit_BGRA(image_reader *reader, Pixel pPixel);
156 
157 
158         // Pixel data readers-
159         // A group of functions for reading Pixelmap output data back into
160         // a Pixel structure. Only supporting 16, 24, and 32 bit formats at first.
161         // FIXME: Need to add 1bpp to 8bpp formats.
162 
163         static Pixel ReadPixelMono(image_reader *reader, int PixIndex);
164         static Pixel ReadPixelMonoTransparent(image_reader *reader, int PixIndex);
165         static Pixel ReadPixel4bppgrayscale(image_reader *reader, int PixIndex);
166         static Pixel ReadPixel4bppgrayscale_transparent(image_reader *reader, int PixIndex);
167         static Pixel ReadPixel8bppPalette(image_reader *reader, int PixIndex);
168         static Pixel ReadPixel8bppAlpha(image_reader *reader, int PixIndex);
169         static Pixel ReadPixel8Bit_332_RGB(image_reader *reader, int PixIndex);
170         static Pixel ReadPixel8Bit_332_Alpha(image_reader *reader, int PixIndex);
171         static Pixel ReadPixel16Bit_555(image_reader *reader, int PixIndex);
172         static Pixel ReadPixel16Bit_555_BGR(image_reader *reader, int PixIndex);
173         static Pixel ReadPixel16Bit_555_Alpha(image_reader *reader, int PixIndex);
174         static Pixel ReadPixel16Bit_565_Alpha(image_reader *reader, int PixIndex);
175         static Pixel ReadPixel16Bit_565_BGR(image_reader *reader, int PixIndex);
176         static Pixel ReadPixel16Bit_565_BGR_Alpha(image_reader *reader, int PixIndex);
177         static Pixel ReadPixel16Bit_565_RGB(image_reader *reader, int PixIndex);
178         static Pixel ReadPixel16Bit_4444_ARGB(image_reader *reader, int PixIndex);
179         static Pixel ReadPixel16Bit_4444_BGRA(image_reader *reader, int PixIndex);
180         static Pixel ReadPixel24Bit_BGRPacked(image_reader *reader, int PixIndex);
181         static Pixel ReadPixel24Bit_RGBPacked(image_reader *reader, int PixIndex);
182         static Pixel ReadPixel32Bit_ARGB(image_reader *reader, int PixIndex);
183         static Pixel ReadPixel32Bit_BGRA(image_reader *reader, int PixIndex);
184 
185         // Functions for writing transparent (not alpha) values in each format
186         static void WriteTransparentPixel_16(UCHAR *pPut, int PixIndex);
187         static void WriteTransparentPixel_24_BGR(UCHAR *pPut, int PixIndex);
188         static void WriteTransparentPixel_24_RGB(UCHAR *pPut, int PixIndex);
189         static void WriteTransparentPixel_32BGRA(UCHAR *pPut, int PixIndex);
190         static void WriteTransparentPixel_32ARGB(UCHAR *pPut, int PixIndex);
191 
192         void BitmapStretch(int src_width, int src_height,
193             int dest_width, int dest_height, GX_PIXELMAP *src, GX_PIXELMAP *dest);
194 
195         void BitmapStretchStep(int dest_width,
196             int source_width, int yCurrent, int yEnd,
197             GX_PIXELMAP *src, GX_PIXELMAP *dest);
198 
199         // pointer to function to read data from incoming source
200         void (*mpReadInputPixel)(image_reader *reader, int index, Pixel *put);
201 
202         // pointer to function to read our output data format, used
203         // by the RLE compression routines.
204         Pixel (*mpReadOutputPixel)(image_reader *reader, int);
205 
206         // pointer to function to write out output data format
207         //
208         // The function must increment the data and aux ptr appropriately,
209         // and return the actual value written (used for dithering error)
210 
211         Pixel (*mpWritePixel)(image_reader *, Pixel);
212 
213         // pointer to function to write transparent value
214         void (*mpWriteTransparentPix)(UCHAR *, int);
215 
216     protected:
217         BOOL mInputHasAlpha;    // does source have alpha channel?
218 
219 
220     private:
221         CArray<GX_PIXELMAP *> mPixelmapList;
222         FILE *mFile;
223         int *mpNextBlueErr;
224         int *mpNextGreenErr;
225         int *mpNextRedErr;
226         int *mpThisBlueErr;
227         int *mpThisGreenErr;
228         int *mpThisRedErr;
229 
230         int mDataSize;
231         int mOutputFormat;
232         int mMode;
233 
234         GX_COLOR *mpPalette;
235         int mPalSize;
236         int mPalFixed;
237 
238         BOOL mWantAlpha;        // does caller want to keep it?
239         BOOL mSaveAlpha;        // save or not save alpha in dest
240 
241         BOOL mDithering;
242         BOOL mDitherDirection;
243         BOOL mTargaFormat;
244         UCHAR   mImageType;
245         UINT    mDisplayFormat;
246 
247         GX_UBYTE *mpPutData;
248         GX_UBYTE *mpPutAux;
249         const GX_UBYTE *mpGetAux;
250         BOOL  mSizeTesting;
251         INT   mGrayThreshod;
252         GX_UBYTE mMonoMask;
253         GX_UBYTE mNibbleMask;
254         BOOL mDoCompress;
255 };
256 
257 // Define input_stream class for reading specified number of bytes from a memory buffer.
258 class input_stream: public IStream
259 {
260 public:
261     input_stream(unsigned char *data, int data_size);
~input_stream()262     ~input_stream() {};
263 
264     // IUnknown Methods
AddRef()265     IFACEMETHODIMP_(ULONG) AddRef() { return 0; }
Release()266     IFACEMETHODIMP_(ULONG) Release() { return 0; }
QueryInterface(REFIID riid,void ** ppInterface)267     IFACEMETHODIMP QueryInterface(REFIID riid, void **ppInterface) { return 0; }
268 
269     // ISequantialStream Methods
270     IFACEMETHODIMP Read(void *pv, ULONG cb, ULONG *pcbRead);
Write(const void * pv,ULONG cb,ULONG * pcbWritten)271     IFACEMETHODIMP Write(const void *pv, ULONG cb, ULONG *pcbWritten) { return 0; }
272 
273     // IStream Methods
Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER * plibNewPosition)274     IFACEMETHODIMP Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { return 0; }
SetSize(ULARGE_INTEGER libNewSize)275     IFACEMETHODIMP SetSize(ULARGE_INTEGER libNewSize) { return 0; }
CopyTo(IStream * pstm,ULARGE_INTEGER cb,ULARGE_INTEGER * pcbRead,ULARGE_INTEGER * pcbWritten)276     IFACEMETHODIMP CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) { return 0; }
Commit(DWORD grfCommitFlags)277     IFACEMETHODIMP Commit(DWORD grfCommitFlags) { return 0; }
Revert(void)278     IFACEMETHODIMP Revert(void) { return 0; }
LockRegion(ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)279     IFACEMETHODIMP LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { return 0; }
UnlockRegion(ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)280     IFACEMETHODIMP UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { return 0; }
Stat(STATSTG * pstatstg,DWORD grfStatFlag)281     IFACEMETHODIMP Stat(STATSTG *pstatstg, DWORD grfStatFlag) { return 0; }
Clone(IStream ** ppstm)282     IFACEMETHODIMP Clone(IStream **ppstm) { return 0; }
283 
284 private:
285     unsigned char* mpData;
286     ULONG mDataSize;
287     ULONG mReadSize;
288 };
289 
290 class png_reader : public image_reader {
291     public:
292         png_reader();
293         virtual ~png_reader();
294         virtual BOOL ReadImage(CString &path, int frame_id = -1);
295         virtual BOOL ReadImage(unsigned char *data, int data_size);
296         virtual BOOL CheckImageHasAlphaChannel(CString &path);
297         virtual INT GetDelayTime(int frame_id = 0) { return 0; }
298 
299     protected:
300          BOOL ReadImage(IStream* input_stream);
301          UCHAR *GetInputDataPtr(int row);
302 
303     private:
304         void ConfigureInternalFormat();
305 
306         static void ReadPixel1(image_reader *reader, int Index, Pixel *put);
307         static void ReadPixel2(image_reader *reader, int Index, Pixel *put);
308         static void ReadPixel4(image_reader *reader, int Index, Pixel *put);
309         static void ReadPixel8(image_reader *reader, int Index, Pixel *put);
310 
311         static void ReadPixel24(image_reader *reader, int Index, Pixel *put);
312         static void ReadPixel48(image_reader *reader, int Index, Pixel *put);
313         static void ReadPixel64(image_reader *reader, int Index, Pixel *put);
314         static void ReadPixel24Alpha(image_reader *reader, int Index, Pixel *put);
315         static void ReadPixel8Alpha(image_reader *reader, int Index, Pixel *put);
316         static void ReadPixel16To8(image_reader *reader, int Index, Pixel *put);
317         static void ReadPixel16Alpha(image_reader *reader, int Index, Pixel *put);
318 
319         static void ReadDataFromIStream(png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead);
320 
321         png_structp m_png;
322         png_infop   m_info;
323         UCHAR   **mpRowPointers;
324 };
325 
326 class jpg_reader : public image_reader {
327     public:
328         jpg_reader();
329         virtual ~jpg_reader();
330         virtual BOOL ReadImage(CString &path, int frame_id = -1);
331         virtual BOOL ReadImage(unsigned char* data, int data_size);
332         virtual INT GetDelayTime(int frame_id = 0) { return 0; }
333 
334     protected:
335          UCHAR *GetInputDataPtr(int row);
336 
337     private:
338         jpeg_decompress_struct mJpgInfo;
339         void ConfigureInternalFormat();
340         UCHAR   *mpRawData;
341         ULONG   mRawRowStride;
342 };
343 
344 class gif_reader : public png_reader {
345 public:
346     gif_reader();
347     virtual ~gif_reader();
348 
349     virtual BOOL ReadImage(CString& path, int frame_id = -1);
350     virtual BOOL ReadImage(unsigned char* data, int data_size);
351     virtual BOOL CheckImageHasAlphaChannel(CString& path);
352     virtual INT GetDelayTime(int frame_id = 0);
353     static INT GetFrameCount(CString& path);
354 
355 private:
356     int GetEncoderClsid(const WCHAR* format, CLSID* pClsid);
357     CArray<UINT> mDelayTimeList;
358 };
359 
360 #endif
361