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