Guillermo Stedile / RA8875

Dependencies:   GPS

Dependents:   SNOCC_V1 SNOCC_V2

Fork of RA8875 by SNOCC

Committer:
WiredHome
Date:
Sun Mar 23 16:27:55 2014 +0000
Revision:
63:ed787f5fcdc4
Adding PNG support - which works for tiny png files but memory requirements may exclude it for larger images.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 63:ed787f5fcdc4 1 //#include <Windows.h>
WiredHome 63:ed787f5fcdc4 2 //#include <stdio.h>
WiredHome 63:ed787f5fcdc4 3
WiredHome 63:ed787f5fcdc4 4 #include "PNG.h"
WiredHome 63:ed787f5fcdc4 5 #include "SlidingWindow.h"
WiredHome 63:ed787f5fcdc4 6
WiredHome 63:ed787f5fcdc4 7 #define DEBUG "PNG "
WiredHome 63:ed787f5fcdc4 8 // ...
WiredHome 63:ed787f5fcdc4 9 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 63:ed787f5fcdc4 10 //
WiredHome 63:ed787f5fcdc4 11 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 63:ed787f5fcdc4 12 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 63:ed787f5fcdc4 13 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 63:ed787f5fcdc4 14 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 63:ed787f5fcdc4 15 #else
WiredHome 63:ed787f5fcdc4 16 #define INFO(x, ...)
WiredHome 63:ed787f5fcdc4 17 #define WARN(x, ...)
WiredHome 63:ed787f5fcdc4 18 #define ERR(x, ...)
WiredHome 63:ed787f5fcdc4 19 #endif
WiredHome 63:ed787f5fcdc4 20
WiredHome 63:ed787f5fcdc4 21 #if 0
WiredHome 63:ed787f5fcdc4 22 static int maxUsed = 0;
WiredHome 63:ed787f5fcdc4 23 static int usedLocs[50000];
WiredHome 63:ed787f5fcdc4 24
WiredHome 63:ed787f5fcdc4 25 void DSTrackClear(void)
WiredHome 63:ed787f5fcdc4 26 {
WiredHome 63:ed787f5fcdc4 27 maxUsed = 0;
WiredHome 63:ed787f5fcdc4 28 for (int i=0; i<5000; i++)
WiredHome 63:ed787f5fcdc4 29 usedLocs[i] = 0;
WiredHome 63:ed787f5fcdc4 30 }
WiredHome 63:ed787f5fcdc4 31 void DSTrackMax(int loc)
WiredHome 63:ed787f5fcdc4 32 {
WiredHome 63:ed787f5fcdc4 33 #if 0
WiredHome 63:ed787f5fcdc4 34 char buf[1000];
WiredHome 63:ed787f5fcdc4 35 sprintf(buf, "using: %5d: ", loc);
WiredHome 63:ed787f5fcdc4 36 for (int i=0; i<loc/100; i++)
WiredHome 63:ed787f5fcdc4 37 strcat(buf," ");
WiredHome 63:ed787f5fcdc4 38 strcat(buf,"*\r\n");
WiredHome 63:ed787f5fcdc4 39 OutputDebugStringA(buf);
WiredHome 63:ed787f5fcdc4 40 if (loc > maxUsed)
WiredHome 63:ed787f5fcdc4 41 maxUsed = loc;
WiredHome 63:ed787f5fcdc4 42 usedLocs[loc] |= 1;
WiredHome 63:ed787f5fcdc4 43 #endif
WiredHome 63:ed787f5fcdc4 44 }
WiredHome 63:ed787f5fcdc4 45 void DSTrackReport(void)
WiredHome 63:ed787f5fcdc4 46 {
WiredHome 63:ed787f5fcdc4 47 #if 0
WiredHome 63:ed787f5fcdc4 48 int totalUsed = 0;
WiredHome 63:ed787f5fcdc4 49 char buf[100];
WiredHome 63:ed787f5fcdc4 50 for (int i=0; i<5000; i++)
WiredHome 63:ed787f5fcdc4 51 totalUsed += usedLocs[i];
WiredHome 63:ed787f5fcdc4 52 sprintf(buf, "Highest used: %d of %d total used\r\n", maxUsed, totalUsed);
WiredHome 63:ed787f5fcdc4 53 OutputDebugStringA(buf);
WiredHome 63:ed787f5fcdc4 54 buf[0] = '\0';
WiredHome 63:ed787f5fcdc4 55 #endif
WiredHome 63:ed787f5fcdc4 56 }
WiredHome 63:ed787f5fcdc4 57 #endif
WiredHome 63:ed787f5fcdc4 58
WiredHome 63:ed787f5fcdc4 59
WiredHome 63:ed787f5fcdc4 60
WiredHome 63:ed787f5fcdc4 61
WiredHome 63:ed787f5fcdc4 62 // Updates
WiredHome 63:ed787f5fcdc4 63 // 2005/03/02
WiredHome 63:ed787f5fcdc4 64 // Started
WiredHome 63:ed787f5fcdc4 65 // 2005/03/03
WiredHome 63:ed787f5fcdc4 66 // Support:
WiredHome 63:ed787f5fcdc4 67 // 8bit Grayscale, True color, 4bit Indexed color, 8bit Indexed color
WiredHome 63:ed787f5fcdc4 68 // 2005/03/04
WiredHome 63:ed787f5fcdc4 69 // Added support for true color with alpha and grayscale with alpha
WiredHome 63:ed787f5fcdc4 70 // 2005/03/14
WiredHome 63:ed787f5fcdc4 71 // Support:
WiredHome 63:ed787f5fcdc4 72 // Interlaced 8bit True color
WiredHome 63:ed787f5fcdc4 73 // 2005/03/15
WiredHome 63:ed787f5fcdc4 74 // Support:
WiredHome 63:ed787f5fcdc4 75 // Interlaced/Non-Interlaced 16bit True color
WiredHome 63:ed787f5fcdc4 76 // Interlaced 8bit Grayscale
WiredHome 63:ed787f5fcdc4 77 // Interlaced 8bit Indexed color
WiredHome 63:ed787f5fcdc4 78 // Interlaced 8bit Grayscale with alpha
WiredHome 63:ed787f5fcdc4 79 // Interlaced 8bit Truecolor with alpha
WiredHome 63:ed787f5fcdc4 80 // Cleaned up a little bit.
WiredHome 63:ed787f5fcdc4 81 // 2005/04/08
WiredHome 63:ed787f5fcdc4 82 // Support:
WiredHome 63:ed787f5fcdc4 83 // Non-Interlace 1 bit Grayscale
WiredHome 63:ed787f5fcdc4 84 // 2010/09/18
WiredHome 63:ed787f5fcdc4 85 // Fixed transparency check in interlaced 16-bit true-color mode.
WiredHome 63:ed787f5fcdc4 86 // Based on a bug-report from a viewer. Thanks for the good catch!
WiredHome 63:ed787f5fcdc4 87 // 2011/12/28
WiredHome 63:ed787f5fcdc4 88 // Fixed transparent color reading based on the user-report. Thanks for the good catch!
WiredHome 63:ed787f5fcdc4 89
WiredHome 63:ed787f5fcdc4 90
WiredHome 63:ed787f5fcdc4 91 /* Supported color and depth
WiredHome 63:ed787f5fcdc4 92
WiredHome 63:ed787f5fcdc4 93 Non-Interlaced
WiredHome 63:ed787f5fcdc4 94 1bit Grayscale
WiredHome 63:ed787f5fcdc4 95 4bit Indexed Color
WiredHome 63:ed787f5fcdc4 96 8bit Grayscale
WiredHome 63:ed787f5fcdc4 97 8bit Grayscale with Alpha
WiredHome 63:ed787f5fcdc4 98 8bit Indexed Color
WiredHome 63:ed787f5fcdc4 99 8bit True Color (24bit per pixel)
WiredHome 63:ed787f5fcdc4 100 8bit True Color with Alpha (32bit per pixel)
WiredHome 63:ed787f5fcdc4 101 16bit True Color (48bit per pixel)
WiredHome 63:ed787f5fcdc4 102
WiredHome 63:ed787f5fcdc4 103 Interlaced
WiredHome 63:ed787f5fcdc4 104 8bit Grayscale
WiredHome 63:ed787f5fcdc4 105 8bit Grayscale with Alpha
WiredHome 63:ed787f5fcdc4 106 8bit Indexed Color
WiredHome 63:ed787f5fcdc4 107 8bit True color (24bit per pixel)
WiredHome 63:ed787f5fcdc4 108 8bit True Color with Alpha (32bit per pixel)
WiredHome 63:ed787f5fcdc4 109 16bit True Color (48bit per pixel)
WiredHome 63:ed787f5fcdc4 110
WiredHome 63:ed787f5fcdc4 111 */
WiredHome 63:ed787f5fcdc4 112
WiredHome 63:ed787f5fcdc4 113
WiredHome 63:ed787f5fcdc4 114
WiredHome 63:ed787f5fcdc4 115 // Memo
WiredHome 63:ed787f5fcdc4 116 // PNG Data Format http://www.w3.org/TR/PNG
WiredHome 63:ed787f5fcdc4 117
WiredHome 63:ed787f5fcdc4 118
WiredHome 63:ed787f5fcdc4 119 #define MakeDword(a,b,c,d) ((a)*0x1000000+(b)*0x10000+(c)*0x100+(d))
WiredHome 63:ed787f5fcdc4 120
WiredHome 63:ed787f5fcdc4 121 #define IHDR MakeDword('I','H','D','R')
WiredHome 63:ed787f5fcdc4 122 #define IDAT MakeDword('I','D','A','T')
WiredHome 63:ed787f5fcdc4 123 #define PLTE MakeDword('P','L','T','E')
WiredHome 63:ed787f5fcdc4 124 #define IEND MakeDword('I','E','N','D')
WiredHome 63:ed787f5fcdc4 125 #define pHYs MakeDword('p','H','y','s')
WiredHome 63:ed787f5fcdc4 126 #define tRNS MakeDword('t','R','N','S')
WiredHome 63:ed787f5fcdc4 127 #define gAMA MakeDword('g','A','M','A')
WiredHome 63:ed787f5fcdc4 128
WiredHome 63:ed787f5fcdc4 129 static inline unsigned int PngGetUnsignedInt(const unsigned char dat[4])
WiredHome 63:ed787f5fcdc4 130 {
WiredHome 63:ed787f5fcdc4 131 return (unsigned)dat[3]+(unsigned)dat[2]*0x100+(unsigned)dat[1]*0x10000+(unsigned)dat[0]*0x1000000;
WiredHome 63:ed787f5fcdc4 132 }
WiredHome 63:ed787f5fcdc4 133
WiredHome 63:ed787f5fcdc4 134 ////////////////////////////////////////////////////////////
WiredHome 63:ed787f5fcdc4 135
WiredHome 63:ed787f5fcdc4 136 void YsPngHeader::Decode(unsigned char dat[])
WiredHome 63:ed787f5fcdc4 137 {
WiredHome 63:ed787f5fcdc4 138 width=PngGetUnsignedInt(dat);
WiredHome 63:ed787f5fcdc4 139 height=PngGetUnsignedInt(dat+4);
WiredHome 63:ed787f5fcdc4 140 bitDepth=dat[8];
WiredHome 63:ed787f5fcdc4 141 colorType=dat[9];
WiredHome 63:ed787f5fcdc4 142 compressionMethod=dat[10];
WiredHome 63:ed787f5fcdc4 143 filterMethod=dat[11];
WiredHome 63:ed787f5fcdc4 144 interlaceMethod=dat[12];
WiredHome 63:ed787f5fcdc4 145
WiredHome 63:ed787f5fcdc4 146 INFO("Width=%d Height=%d",width,height);
WiredHome 63:ed787f5fcdc4 147 INFO("bitDepth=%d",bitDepth);
WiredHome 63:ed787f5fcdc4 148 INFO("colorType=%d",colorType);
WiredHome 63:ed787f5fcdc4 149 INFO("compressionMethod=%d",compressionMethod);
WiredHome 63:ed787f5fcdc4 150 INFO("filterMethod=%d",filterMethod);
WiredHome 63:ed787f5fcdc4 151 INFO("interlaceMethod=%d",interlaceMethod);
WiredHome 63:ed787f5fcdc4 152 }
WiredHome 63:ed787f5fcdc4 153
WiredHome 63:ed787f5fcdc4 154 YsPngPalette::YsPngPalette()
WiredHome 63:ed787f5fcdc4 155 {
WiredHome 63:ed787f5fcdc4 156 nEntry=0;
WiredHome 63:ed787f5fcdc4 157 entry=NULL;
WiredHome 63:ed787f5fcdc4 158 }
WiredHome 63:ed787f5fcdc4 159
WiredHome 63:ed787f5fcdc4 160 YsPngPalette::~YsPngPalette()
WiredHome 63:ed787f5fcdc4 161 {
WiredHome 63:ed787f5fcdc4 162 if(entry!=NULL)
WiredHome 63:ed787f5fcdc4 163 {
WiredHome 63:ed787f5fcdc4 164 delete [] entry;
WiredHome 63:ed787f5fcdc4 165 }
WiredHome 63:ed787f5fcdc4 166 }
WiredHome 63:ed787f5fcdc4 167
WiredHome 63:ed787f5fcdc4 168 int YsPngPalette::Decode(unsigned length,unsigned char dat[])
WiredHome 63:ed787f5fcdc4 169 {
WiredHome 63:ed787f5fcdc4 170 if(length%3!=0)
WiredHome 63:ed787f5fcdc4 171 {
WiredHome 63:ed787f5fcdc4 172 return YSERR;
WiredHome 63:ed787f5fcdc4 173 }
WiredHome 63:ed787f5fcdc4 174
WiredHome 63:ed787f5fcdc4 175 if(entry!=NULL)
WiredHome 63:ed787f5fcdc4 176 {
WiredHome 63:ed787f5fcdc4 177 delete [] entry;
WiredHome 63:ed787f5fcdc4 178 nEntry=0;
WiredHome 63:ed787f5fcdc4 179 entry=NULL;
WiredHome 63:ed787f5fcdc4 180 }
WiredHome 63:ed787f5fcdc4 181
WiredHome 63:ed787f5fcdc4 182 if(length>0)
WiredHome 63:ed787f5fcdc4 183 {
WiredHome 63:ed787f5fcdc4 184 entry=new unsigned char [length];
WiredHome 63:ed787f5fcdc4 185 if(entry!=NULL)
WiredHome 63:ed787f5fcdc4 186 {
WiredHome 63:ed787f5fcdc4 187 unsigned int i;
WiredHome 63:ed787f5fcdc4 188 nEntry=length/3;
WiredHome 63:ed787f5fcdc4 189
WiredHome 63:ed787f5fcdc4 190 INFO("%d palette entries",nEntry);
WiredHome 63:ed787f5fcdc4 191 for(i=0; i<length; i++)
WiredHome 63:ed787f5fcdc4 192 {
WiredHome 63:ed787f5fcdc4 193 entry[i]=dat[i];
WiredHome 63:ed787f5fcdc4 194 }
WiredHome 63:ed787f5fcdc4 195 }
WiredHome 63:ed787f5fcdc4 196 }
WiredHome 63:ed787f5fcdc4 197
WiredHome 63:ed787f5fcdc4 198 return YSOK;
WiredHome 63:ed787f5fcdc4 199 }
WiredHome 63:ed787f5fcdc4 200
WiredHome 63:ed787f5fcdc4 201 ////////////////////////////////////////////////////////////
WiredHome 63:ed787f5fcdc4 202
WiredHome 63:ed787f5fcdc4 203 int YsPngTransparency::Decode(unsigned int length,unsigned char dat[],unsigned int colorType)
WiredHome 63:ed787f5fcdc4 204 {
WiredHome 63:ed787f5fcdc4 205 unsigned int i;
WiredHome 63:ed787f5fcdc4 206 switch(colorType)
WiredHome 63:ed787f5fcdc4 207 {
WiredHome 63:ed787f5fcdc4 208 case 0:
WiredHome 63:ed787f5fcdc4 209 if(length>=2)
WiredHome 63:ed787f5fcdc4 210 {
WiredHome 63:ed787f5fcdc4 211 col[0]=(unsigned int)dat[0]*256+(unsigned int)dat[1];
WiredHome 63:ed787f5fcdc4 212 return YSOK;
WiredHome 63:ed787f5fcdc4 213 }
WiredHome 63:ed787f5fcdc4 214 break;
WiredHome 63:ed787f5fcdc4 215 case 2:
WiredHome 63:ed787f5fcdc4 216 if(length>=6)
WiredHome 63:ed787f5fcdc4 217 {
WiredHome 63:ed787f5fcdc4 218 col[0]=(unsigned int)dat[0]*256+(unsigned int)dat[1]; // 2011/12/28 Bug fix based on the user-report. Thanks!
WiredHome 63:ed787f5fcdc4 219 col[1]=(unsigned int)dat[2]*256+(unsigned int)dat[3];
WiredHome 63:ed787f5fcdc4 220 col[2]=(unsigned int)dat[4]*256+(unsigned int)dat[5];
WiredHome 63:ed787f5fcdc4 221 return YSOK;
WiredHome 63:ed787f5fcdc4 222 }
WiredHome 63:ed787f5fcdc4 223 break;
WiredHome 63:ed787f5fcdc4 224 case 3:
WiredHome 63:ed787f5fcdc4 225 for(i=0; i<3 && i<length; i++)
WiredHome 63:ed787f5fcdc4 226 {
WiredHome 63:ed787f5fcdc4 227 col[i]=dat[i];
WiredHome 63:ed787f5fcdc4 228 }
WiredHome 63:ed787f5fcdc4 229 return YSOK;
WiredHome 63:ed787f5fcdc4 230 }
WiredHome 63:ed787f5fcdc4 231 return YSERR;
WiredHome 63:ed787f5fcdc4 232 }
WiredHome 63:ed787f5fcdc4 233
WiredHome 63:ed787f5fcdc4 234 ////////////////////////////////////////////////////////////
WiredHome 63:ed787f5fcdc4 235
WiredHome 63:ed787f5fcdc4 236 YsGenericPngDecoder::YsGenericPngDecoder()
WiredHome 63:ed787f5fcdc4 237 {
WiredHome 63:ed787f5fcdc4 238 Initialize();
WiredHome 63:ed787f5fcdc4 239 }
WiredHome 63:ed787f5fcdc4 240
WiredHome 63:ed787f5fcdc4 241 void YsGenericPngDecoder::Initialize(void)
WiredHome 63:ed787f5fcdc4 242 {
WiredHome 63:ed787f5fcdc4 243 gamma=gamma_default;
WiredHome 63:ed787f5fcdc4 244 trns.col[0]=0x7fffffff;
WiredHome 63:ed787f5fcdc4 245 trns.col[1]=0x7fffffff;
WiredHome 63:ed787f5fcdc4 246 trns.col[2]=0x7fffffff;
WiredHome 63:ed787f5fcdc4 247 }
WiredHome 63:ed787f5fcdc4 248
WiredHome 63:ed787f5fcdc4 249 int YsGenericPngDecoder::CheckSignature(FILE *fp)
WiredHome 63:ed787f5fcdc4 250 {
WiredHome 63:ed787f5fcdc4 251 unsigned char buf[8];
WiredHome 63:ed787f5fcdc4 252 fread(buf,1,8,fp);
WiredHome 63:ed787f5fcdc4 253 if(buf[0]==0x89 && buf[1]==0x50 && buf[2]==0x4e && buf[3]==0x47 &&
WiredHome 63:ed787f5fcdc4 254 buf[4]==0x0d && buf[5]==0x0a && buf[6]==0x1a && buf[7]==0x0a)
WiredHome 63:ed787f5fcdc4 255 {
WiredHome 63:ed787f5fcdc4 256 return YSOK;
WiredHome 63:ed787f5fcdc4 257 }
WiredHome 63:ed787f5fcdc4 258 return YSERR;
WiredHome 63:ed787f5fcdc4 259 }
WiredHome 63:ed787f5fcdc4 260
WiredHome 63:ed787f5fcdc4 261 int YsGenericPngDecoder::ReadChunk(unsigned &length,unsigned char *&buf,unsigned &chunkType,unsigned &crc,FILE *fp)
WiredHome 63:ed787f5fcdc4 262 {
WiredHome 63:ed787f5fcdc4 263 unsigned char dwBuf[4];
WiredHome 63:ed787f5fcdc4 264
WiredHome 63:ed787f5fcdc4 265 if(fread(dwBuf,1,4,fp)<4)
WiredHome 63:ed787f5fcdc4 266 {
WiredHome 63:ed787f5fcdc4 267 return YSERR;
WiredHome 63:ed787f5fcdc4 268 }
WiredHome 63:ed787f5fcdc4 269 length=PngGetUnsignedInt(dwBuf);
WiredHome 63:ed787f5fcdc4 270
WiredHome 63:ed787f5fcdc4 271 if(fread(dwBuf,1,4,fp)<4)
WiredHome 63:ed787f5fcdc4 272 {
WiredHome 63:ed787f5fcdc4 273 return YSERR;
WiredHome 63:ed787f5fcdc4 274 }
WiredHome 63:ed787f5fcdc4 275 chunkType=PngGetUnsignedInt(dwBuf);
WiredHome 63:ed787f5fcdc4 276
WiredHome 63:ed787f5fcdc4 277 INFO("Chunk name=%c%c%c%c",dwBuf[0],dwBuf[1],dwBuf[2],dwBuf[3]);
WiredHome 63:ed787f5fcdc4 278
WiredHome 63:ed787f5fcdc4 279 if(length>0)
WiredHome 63:ed787f5fcdc4 280 {
WiredHome 63:ed787f5fcdc4 281 buf=new unsigned char [length];
WiredHome 63:ed787f5fcdc4 282 if(fread(buf,1,length,fp)<length)
WiredHome 63:ed787f5fcdc4 283 {
WiredHome 63:ed787f5fcdc4 284 return YSERR;
WiredHome 63:ed787f5fcdc4 285 }
WiredHome 63:ed787f5fcdc4 286 }
WiredHome 63:ed787f5fcdc4 287 else
WiredHome 63:ed787f5fcdc4 288 {
WiredHome 63:ed787f5fcdc4 289 buf=NULL;
WiredHome 63:ed787f5fcdc4 290 }
WiredHome 63:ed787f5fcdc4 291
WiredHome 63:ed787f5fcdc4 292 if(fread(dwBuf,1,4,fp)<4)
WiredHome 63:ed787f5fcdc4 293 {
WiredHome 63:ed787f5fcdc4 294 return YSERR;
WiredHome 63:ed787f5fcdc4 295 }
WiredHome 63:ed787f5fcdc4 296 crc=PngGetUnsignedInt(dwBuf);
WiredHome 63:ed787f5fcdc4 297
WiredHome 63:ed787f5fcdc4 298 return YSOK;
WiredHome 63:ed787f5fcdc4 299 }
WiredHome 63:ed787f5fcdc4 300
WiredHome 63:ed787f5fcdc4 301 ////////////////////////////////////////////////////////////
WiredHome 63:ed787f5fcdc4 302
WiredHome 63:ed787f5fcdc4 303 int YsPngHuffmanTree::leakTracker=0;
WiredHome 63:ed787f5fcdc4 304
WiredHome 63:ed787f5fcdc4 305 YsPngHuffmanTree::YsPngHuffmanTree()
WiredHome 63:ed787f5fcdc4 306 {
WiredHome 63:ed787f5fcdc4 307 zero=NULL;
WiredHome 63:ed787f5fcdc4 308 one=NULL;
WiredHome 63:ed787f5fcdc4 309 dat=0x7fffffff;
WiredHome 63:ed787f5fcdc4 310 weight=0;
WiredHome 63:ed787f5fcdc4 311 depth=1;
WiredHome 63:ed787f5fcdc4 312 leakTracker++;
WiredHome 63:ed787f5fcdc4 313 }
WiredHome 63:ed787f5fcdc4 314
WiredHome 63:ed787f5fcdc4 315 YsPngHuffmanTree::~YsPngHuffmanTree()
WiredHome 63:ed787f5fcdc4 316 {
WiredHome 63:ed787f5fcdc4 317 leakTracker--;
WiredHome 63:ed787f5fcdc4 318 }
WiredHome 63:ed787f5fcdc4 319
WiredHome 63:ed787f5fcdc4 320 void YsPngHuffmanTree::DeleteHuffmanTree(YsPngHuffmanTree *node)
WiredHome 63:ed787f5fcdc4 321 {
WiredHome 63:ed787f5fcdc4 322 if(node!=NULL)
WiredHome 63:ed787f5fcdc4 323 {
WiredHome 63:ed787f5fcdc4 324 DeleteHuffmanTree(node->zero);
WiredHome 63:ed787f5fcdc4 325 DeleteHuffmanTree(node->one);
WiredHome 63:ed787f5fcdc4 326 delete node;
WiredHome 63:ed787f5fcdc4 327 }
WiredHome 63:ed787f5fcdc4 328 }
WiredHome 63:ed787f5fcdc4 329
WiredHome 63:ed787f5fcdc4 330 ////////////////////////////////////////////////////////////
WiredHome 63:ed787f5fcdc4 331
WiredHome 63:ed787f5fcdc4 332 void YsPngUncompressor::MakeFixedHuffmanCode(unsigned hLength[288],unsigned hCode[288])
WiredHome 63:ed787f5fcdc4 333 {
WiredHome 63:ed787f5fcdc4 334 unsigned i;
WiredHome 63:ed787f5fcdc4 335 for(i=0; i<=143; i++)
WiredHome 63:ed787f5fcdc4 336 {
WiredHome 63:ed787f5fcdc4 337 hLength[i]=8;
WiredHome 63:ed787f5fcdc4 338 hCode[i]=0x30+i;
WiredHome 63:ed787f5fcdc4 339 }
WiredHome 63:ed787f5fcdc4 340 for(i=144; i<=255; i++)
WiredHome 63:ed787f5fcdc4 341 {
WiredHome 63:ed787f5fcdc4 342 hLength[i]=9;
WiredHome 63:ed787f5fcdc4 343 hCode[i]=0x190+(i-144);
WiredHome 63:ed787f5fcdc4 344 }
WiredHome 63:ed787f5fcdc4 345 for(i=256; i<=279; i++)
WiredHome 63:ed787f5fcdc4 346 {
WiredHome 63:ed787f5fcdc4 347 hLength[i]=7;
WiredHome 63:ed787f5fcdc4 348 hCode[i]=i-256;
WiredHome 63:ed787f5fcdc4 349 }
WiredHome 63:ed787f5fcdc4 350 for(i=280; i<=287; i++)
WiredHome 63:ed787f5fcdc4 351 {
WiredHome 63:ed787f5fcdc4 352 hLength[i]=8;
WiredHome 63:ed787f5fcdc4 353 hCode[i]=0xc0+(i-280);
WiredHome 63:ed787f5fcdc4 354 }
WiredHome 63:ed787f5fcdc4 355 }
WiredHome 63:ed787f5fcdc4 356
WiredHome 63:ed787f5fcdc4 357 void YsPngUncompressor::MakeDynamicHuffmanCode(unsigned hLength[],unsigned hCode[],unsigned nLng,unsigned lng[])
WiredHome 63:ed787f5fcdc4 358 {
WiredHome 63:ed787f5fcdc4 359 unsigned i,maxLng,code,*bl_count,*next_code,bits,n;
WiredHome 63:ed787f5fcdc4 360
WiredHome 63:ed787f5fcdc4 361 for(i=0; i<nLng; i++)
WiredHome 63:ed787f5fcdc4 362 {
WiredHome 63:ed787f5fcdc4 363 hLength[i]=lng[i];
WiredHome 63:ed787f5fcdc4 364 hCode[i]=0;
WiredHome 63:ed787f5fcdc4 365 }
WiredHome 63:ed787f5fcdc4 366
WiredHome 63:ed787f5fcdc4 367 maxLng=0;
WiredHome 63:ed787f5fcdc4 368 for(i=0; i<nLng; i++)
WiredHome 63:ed787f5fcdc4 369 {
WiredHome 63:ed787f5fcdc4 370 if(maxLng<lng[i])
WiredHome 63:ed787f5fcdc4 371 {
WiredHome 63:ed787f5fcdc4 372 maxLng=lng[i];
WiredHome 63:ed787f5fcdc4 373 }
WiredHome 63:ed787f5fcdc4 374 }
WiredHome 63:ed787f5fcdc4 375
WiredHome 63:ed787f5fcdc4 376 bl_count=new unsigned [maxLng+1];
WiredHome 63:ed787f5fcdc4 377 next_code=new unsigned [maxLng+1];
WiredHome 63:ed787f5fcdc4 378 for(i=0; i<maxLng+1; i++)
WiredHome 63:ed787f5fcdc4 379 {
WiredHome 63:ed787f5fcdc4 380 bl_count[i]=0;
WiredHome 63:ed787f5fcdc4 381 next_code[i]=0;
WiredHome 63:ed787f5fcdc4 382 }
WiredHome 63:ed787f5fcdc4 383 for(i=0; i<nLng; i++)
WiredHome 63:ed787f5fcdc4 384 {
WiredHome 63:ed787f5fcdc4 385 bl_count[lng[i]]++;
WiredHome 63:ed787f5fcdc4 386 }
WiredHome 63:ed787f5fcdc4 387
WiredHome 63:ed787f5fcdc4 388 // for(i=0; i<maxLng+1; i++)
WiredHome 63:ed787f5fcdc4 389 // {
WiredHome 63:ed787f5fcdc4 390 // INFO("bl_count[%d]=%d",i,bl_count[i]);
WiredHome 63:ed787f5fcdc4 391 // }
WiredHome 63:ed787f5fcdc4 392
WiredHome 63:ed787f5fcdc4 393 // See RFC1951 Specification
WiredHome 63:ed787f5fcdc4 394 code=0;
WiredHome 63:ed787f5fcdc4 395 bl_count[0]=0;
WiredHome 63:ed787f5fcdc4 396 for(bits=1; bits<=maxLng; bits++)
WiredHome 63:ed787f5fcdc4 397 {
WiredHome 63:ed787f5fcdc4 398 code=(code+bl_count[bits-1])<<1;
WiredHome 63:ed787f5fcdc4 399 next_code[bits]=code;
WiredHome 63:ed787f5fcdc4 400 }
WiredHome 63:ed787f5fcdc4 401
WiredHome 63:ed787f5fcdc4 402 for(n=0; n<nLng; n++)
WiredHome 63:ed787f5fcdc4 403 {
WiredHome 63:ed787f5fcdc4 404 unsigned len;
WiredHome 63:ed787f5fcdc4 405 len=lng[n];
WiredHome 63:ed787f5fcdc4 406 if(len>0)
WiredHome 63:ed787f5fcdc4 407 {
WiredHome 63:ed787f5fcdc4 408 hCode[n]=next_code[len]++;
WiredHome 63:ed787f5fcdc4 409 }
WiredHome 63:ed787f5fcdc4 410 }
WiredHome 63:ed787f5fcdc4 411
WiredHome 63:ed787f5fcdc4 412 if(bl_count!=NULL)
WiredHome 63:ed787f5fcdc4 413 {
WiredHome 63:ed787f5fcdc4 414 delete [] bl_count;
WiredHome 63:ed787f5fcdc4 415 }
WiredHome 63:ed787f5fcdc4 416 if(next_code!=NULL)
WiredHome 63:ed787f5fcdc4 417 {
WiredHome 63:ed787f5fcdc4 418 delete [] next_code;
WiredHome 63:ed787f5fcdc4 419 }
WiredHome 63:ed787f5fcdc4 420 }
WiredHome 63:ed787f5fcdc4 421
WiredHome 63:ed787f5fcdc4 422 int YsPngUncompressor::DecodeDynamicHuffmanCode
WiredHome 63:ed787f5fcdc4 423 (unsigned int &hLit,unsigned int &hDist,unsigned int &hCLen,
WiredHome 63:ed787f5fcdc4 424 unsigned int *&hLengthLiteral,unsigned int *&hCodeLiteral,
WiredHome 63:ed787f5fcdc4 425 unsigned int *&hLengthDist,unsigned int *&hCodeDist,
WiredHome 63:ed787f5fcdc4 426 unsigned int hLengthBuf[322],unsigned int hCodeBuf[322],
WiredHome 63:ed787f5fcdc4 427 const unsigned char dat[],unsigned int &bytePtr,unsigned int &bitPtr)
WiredHome 63:ed787f5fcdc4 428 {
WiredHome 63:ed787f5fcdc4 429 unsigned int i;
WiredHome 63:ed787f5fcdc4 430 hLit=0;
WiredHome 63:ed787f5fcdc4 431 hDist=0;
WiredHome 63:ed787f5fcdc4 432 hCLen=0;
WiredHome 63:ed787f5fcdc4 433
WiredHome 63:ed787f5fcdc4 434 hLit=GetNextMultiBit(dat,bytePtr,bitPtr,5);
WiredHome 63:ed787f5fcdc4 435 hDist=GetNextMultiBit(dat,bytePtr,bitPtr,5);
WiredHome 63:ed787f5fcdc4 436 hCLen=GetNextMultiBit(dat,bytePtr,bitPtr,4);
WiredHome 63:ed787f5fcdc4 437
WiredHome 63:ed787f5fcdc4 438 INFO("hLit=%d hDist=%d hCLen=%d",hLit,hDist,hCLen);
WiredHome 63:ed787f5fcdc4 439
WiredHome 63:ed787f5fcdc4 440 const unsigned int codeLengthLen=19;
WiredHome 63:ed787f5fcdc4 441 unsigned codeLengthOrder[codeLengthLen]=
WiredHome 63:ed787f5fcdc4 442 {
WiredHome 63:ed787f5fcdc4 443 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
WiredHome 63:ed787f5fcdc4 444 };
WiredHome 63:ed787f5fcdc4 445 unsigned codeLengthCode[codeLengthLen];
WiredHome 63:ed787f5fcdc4 446 for(i=0; i<codeLengthLen; i++)
WiredHome 63:ed787f5fcdc4 447 {
WiredHome 63:ed787f5fcdc4 448 codeLengthCode[i]=0;
WiredHome 63:ed787f5fcdc4 449 }
WiredHome 63:ed787f5fcdc4 450 for(i=0; i<hCLen+4; i++)
WiredHome 63:ed787f5fcdc4 451 {
WiredHome 63:ed787f5fcdc4 452 codeLengthCode[codeLengthOrder[i]]=GetNextMultiBit(dat,bytePtr,bitPtr,3);
WiredHome 63:ed787f5fcdc4 453 // INFO("Code length code[%d]=%d (for %d)",
WiredHome 63:ed787f5fcdc4 454 // codeLengthOrder[i],codeLengthCode[i],codeLengthOrder[i]);
WiredHome 63:ed787f5fcdc4 455 }
WiredHome 63:ed787f5fcdc4 456
WiredHome 63:ed787f5fcdc4 457 unsigned hLengthCode[codeLengthLen],hCodeCode[codeLengthLen];
WiredHome 63:ed787f5fcdc4 458 MakeDynamicHuffmanCode(hLengthCode,hCodeCode,codeLengthLen,codeLengthCode);
WiredHome 63:ed787f5fcdc4 459
WiredHome 63:ed787f5fcdc4 460 for(i=0; i<hCLen+4; i++)
WiredHome 63:ed787f5fcdc4 461 {
WiredHome 63:ed787f5fcdc4 462 INFO("CodeLengthLen[%3d]=%d HuffmanCode=%08x",i,codeLengthCode[i],hCodeCode[i]);
WiredHome 63:ed787f5fcdc4 463 }
WiredHome 63:ed787f5fcdc4 464
WiredHome 63:ed787f5fcdc4 465 // for(i=0; i<codeLengthLen; i++)
WiredHome 63:ed787f5fcdc4 466 // {
WiredHome 63:ed787f5fcdc4 467 // INFO("[%d] %08x %08xx",i,hLengthCode[i],hCodeCode[i]);
WiredHome 63:ed787f5fcdc4 468 // }
WiredHome 63:ed787f5fcdc4 469
WiredHome 63:ed787f5fcdc4 470 hLengthLiteral=hLengthBuf;
WiredHome 63:ed787f5fcdc4 471 hCodeLiteral=hCodeBuf;
WiredHome 63:ed787f5fcdc4 472 hLengthDist=hLengthBuf+hLit+257;
WiredHome 63:ed787f5fcdc4 473 hCodeDist=hCodeBuf+hLit+257;
WiredHome 63:ed787f5fcdc4 474
WiredHome 63:ed787f5fcdc4 475 YsPngHuffmanTree *lengthTree,*lengthTreePtr;
WiredHome 63:ed787f5fcdc4 476 lengthTree=MakeHuffmanTree(codeLengthLen,hLengthCode,hCodeCode);
WiredHome 63:ed787f5fcdc4 477
WiredHome 63:ed787f5fcdc4 478 unsigned int nExtr;
WiredHome 63:ed787f5fcdc4 479 nExtr=0;
WiredHome 63:ed787f5fcdc4 480 lengthTreePtr=lengthTree;
WiredHome 63:ed787f5fcdc4 481 while(nExtr<hLit+257+hDist+1)
WiredHome 63:ed787f5fcdc4 482 {
WiredHome 63:ed787f5fcdc4 483 if(GetNextBit(dat,bytePtr,bitPtr))
WiredHome 63:ed787f5fcdc4 484 {
WiredHome 63:ed787f5fcdc4 485 lengthTreePtr=lengthTreePtr->one;
WiredHome 63:ed787f5fcdc4 486 }
WiredHome 63:ed787f5fcdc4 487 else
WiredHome 63:ed787f5fcdc4 488 {
WiredHome 63:ed787f5fcdc4 489 lengthTreePtr=lengthTreePtr->zero;
WiredHome 63:ed787f5fcdc4 490 }
WiredHome 63:ed787f5fcdc4 491 if(lengthTreePtr->zero==NULL && lengthTreePtr->one==NULL)
WiredHome 63:ed787f5fcdc4 492 {
WiredHome 63:ed787f5fcdc4 493 unsigned value,copyLength;
WiredHome 63:ed787f5fcdc4 494 value=lengthTreePtr->dat;
WiredHome 63:ed787f5fcdc4 495
WiredHome 63:ed787f5fcdc4 496 // INFO("Value=%d",value);
WiredHome 63:ed787f5fcdc4 497
WiredHome 63:ed787f5fcdc4 498 if(value<=15)
WiredHome 63:ed787f5fcdc4 499 {
WiredHome 63:ed787f5fcdc4 500 hLengthBuf[nExtr++]=value;
WiredHome 63:ed787f5fcdc4 501 }
WiredHome 63:ed787f5fcdc4 502 else if(value==16)
WiredHome 63:ed787f5fcdc4 503 {
WiredHome 63:ed787f5fcdc4 504 copyLength=3+GetNextMultiBit(dat,bytePtr,bitPtr,2);
WiredHome 63:ed787f5fcdc4 505 // INFO("copyLength=%d",copyLength);
WiredHome 63:ed787f5fcdc4 506 while(copyLength>0)
WiredHome 63:ed787f5fcdc4 507 {
WiredHome 63:ed787f5fcdc4 508 hLengthBuf[nExtr]=hLengthBuf[nExtr-1];
WiredHome 63:ed787f5fcdc4 509 nExtr++;
WiredHome 63:ed787f5fcdc4 510 copyLength--;
WiredHome 63:ed787f5fcdc4 511 }
WiredHome 63:ed787f5fcdc4 512 }
WiredHome 63:ed787f5fcdc4 513 else if(value==17)
WiredHome 63:ed787f5fcdc4 514 {
WiredHome 63:ed787f5fcdc4 515 copyLength=3+GetNextMultiBit(dat,bytePtr,bitPtr,3);
WiredHome 63:ed787f5fcdc4 516 // INFO("copyLength=%d",copyLength);
WiredHome 63:ed787f5fcdc4 517 while(copyLength>0)
WiredHome 63:ed787f5fcdc4 518 {
WiredHome 63:ed787f5fcdc4 519 hLengthBuf[nExtr++]=0;
WiredHome 63:ed787f5fcdc4 520 copyLength--;
WiredHome 63:ed787f5fcdc4 521 }
WiredHome 63:ed787f5fcdc4 522 }
WiredHome 63:ed787f5fcdc4 523 else if(value==18)
WiredHome 63:ed787f5fcdc4 524 {
WiredHome 63:ed787f5fcdc4 525 copyLength=11+GetNextMultiBit(dat,bytePtr,bitPtr,7);
WiredHome 63:ed787f5fcdc4 526 // INFO("copyLength=%d",copyLength);
WiredHome 63:ed787f5fcdc4 527 while(copyLength>0)
WiredHome 63:ed787f5fcdc4 528 {
WiredHome 63:ed787f5fcdc4 529 hLengthBuf[nExtr++]=0;
WiredHome 63:ed787f5fcdc4 530 copyLength--;
WiredHome 63:ed787f5fcdc4 531 }
WiredHome 63:ed787f5fcdc4 532 }
WiredHome 63:ed787f5fcdc4 533
WiredHome 63:ed787f5fcdc4 534 lengthTreePtr=lengthTree;
WiredHome 63:ed787f5fcdc4 535
WiredHome 63:ed787f5fcdc4 536 // INFO("nExtr=%d/%d",nExtr,hLit+257+hDist+1);
WiredHome 63:ed787f5fcdc4 537 }
WiredHome 63:ed787f5fcdc4 538 }
WiredHome 63:ed787f5fcdc4 539
WiredHome 63:ed787f5fcdc4 540 for(i=0; i<hLit+257; i++)
WiredHome 63:ed787f5fcdc4 541 {
WiredHome 63:ed787f5fcdc4 542 INFO("LiteralLength[%3d]=%d",i,hLengthLiteral[i]);
WiredHome 63:ed787f5fcdc4 543 }
WiredHome 63:ed787f5fcdc4 544 for(i=0; i<hDist+1; i++)
WiredHome 63:ed787f5fcdc4 545 {
WiredHome 63:ed787f5fcdc4 546 INFO("Dist [%d] Length %d",i,hLengthDist[i]);
WiredHome 63:ed787f5fcdc4 547 }
WiredHome 63:ed787f5fcdc4 548 INFO("Making Huffman Code from Code Lengths");
WiredHome 63:ed787f5fcdc4 549
WiredHome 63:ed787f5fcdc4 550 MakeDynamicHuffmanCode(hLengthLiteral,hCodeLiteral,hLit+257,hLengthLiteral);
WiredHome 63:ed787f5fcdc4 551 MakeDynamicHuffmanCode(hLengthDist,hCodeDist,hDist+1,hLengthDist);
WiredHome 63:ed787f5fcdc4 552
WiredHome 63:ed787f5fcdc4 553 DeleteHuffmanTree(lengthTree);
WiredHome 63:ed787f5fcdc4 554
WiredHome 63:ed787f5fcdc4 555 return YSOK;
WiredHome 63:ed787f5fcdc4 556 }
WiredHome 63:ed787f5fcdc4 557
WiredHome 63:ed787f5fcdc4 558 YsPngHuffmanTree *YsPngUncompressor::MakeHuffmanTree(unsigned n,unsigned hLength[],unsigned hCode[])
WiredHome 63:ed787f5fcdc4 559 {
WiredHome 63:ed787f5fcdc4 560 unsigned i,j,mask;
WiredHome 63:ed787f5fcdc4 561 YsPngHuffmanTree *root,*ptr;
WiredHome 63:ed787f5fcdc4 562 root=new YsPngHuffmanTree;
WiredHome 63:ed787f5fcdc4 563
WiredHome 63:ed787f5fcdc4 564 for(i=0; i<n; i++)
WiredHome 63:ed787f5fcdc4 565 {
WiredHome 63:ed787f5fcdc4 566 INFO(" MakeHuffmanTree %d of %d", i, n);
WiredHome 63:ed787f5fcdc4 567 if(hLength[i]>0)
WiredHome 63:ed787f5fcdc4 568 {
WiredHome 63:ed787f5fcdc4 569 ptr=root;
WiredHome 63:ed787f5fcdc4 570 mask=(1<<(hLength[i]-1));
WiredHome 63:ed787f5fcdc4 571 for(j=0; j<hLength[i]; j++)
WiredHome 63:ed787f5fcdc4 572 {
WiredHome 63:ed787f5fcdc4 573 INFO(" j: %d of %d", j, hLength[i]);
WiredHome 63:ed787f5fcdc4 574 if(hCode[i]&mask)
WiredHome 63:ed787f5fcdc4 575 {
WiredHome 63:ed787f5fcdc4 576 if(ptr->one==NULL)
WiredHome 63:ed787f5fcdc4 577 {
WiredHome 63:ed787f5fcdc4 578 ptr->one=new YsPngHuffmanTree;
WiredHome 63:ed787f5fcdc4 579 }
WiredHome 63:ed787f5fcdc4 580 ptr=ptr->one;
WiredHome 63:ed787f5fcdc4 581 }
WiredHome 63:ed787f5fcdc4 582 else
WiredHome 63:ed787f5fcdc4 583 {
WiredHome 63:ed787f5fcdc4 584 if(ptr->zero==NULL)
WiredHome 63:ed787f5fcdc4 585 {
WiredHome 63:ed787f5fcdc4 586 ptr->zero=new YsPngHuffmanTree;
WiredHome 63:ed787f5fcdc4 587 }
WiredHome 63:ed787f5fcdc4 588 ptr=ptr->zero;
WiredHome 63:ed787f5fcdc4 589 }
WiredHome 63:ed787f5fcdc4 590 mask>>=1;
WiredHome 63:ed787f5fcdc4 591 }
WiredHome 63:ed787f5fcdc4 592 ptr->dat=i;
WiredHome 63:ed787f5fcdc4 593 }
WiredHome 63:ed787f5fcdc4 594 }
WiredHome 63:ed787f5fcdc4 595
WiredHome 63:ed787f5fcdc4 596 return root;
WiredHome 63:ed787f5fcdc4 597 }
WiredHome 63:ed787f5fcdc4 598
WiredHome 63:ed787f5fcdc4 599 void YsPngUncompressor::DeleteHuffmanTree(YsPngHuffmanTree *node)
WiredHome 63:ed787f5fcdc4 600 {
WiredHome 63:ed787f5fcdc4 601 INFO("DeleteHuffmanTree");
WiredHome 63:ed787f5fcdc4 602 YsPngHuffmanTree::DeleteHuffmanTree(node);
WiredHome 63:ed787f5fcdc4 603 }
WiredHome 63:ed787f5fcdc4 604
WiredHome 63:ed787f5fcdc4 605 unsigned YsPngUncompressor::GetCopyLength(unsigned value,unsigned char dat[],unsigned &bytePtr,unsigned &bitPtr)
WiredHome 63:ed787f5fcdc4 606 {
WiredHome 63:ed787f5fcdc4 607 unsigned copyLength;
WiredHome 63:ed787f5fcdc4 608
WiredHome 63:ed787f5fcdc4 609 if(value<=264)
WiredHome 63:ed787f5fcdc4 610 {
WiredHome 63:ed787f5fcdc4 611 copyLength=3+(value-257);
WiredHome 63:ed787f5fcdc4 612 }
WiredHome 63:ed787f5fcdc4 613 else if(value>=285)
WiredHome 63:ed787f5fcdc4 614 {
WiredHome 63:ed787f5fcdc4 615 copyLength=258;
WiredHome 63:ed787f5fcdc4 616 }
WiredHome 63:ed787f5fcdc4 617 else
WiredHome 63:ed787f5fcdc4 618 {
WiredHome 63:ed787f5fcdc4 619 unsigned base,offset,extBits;
WiredHome 63:ed787f5fcdc4 620 extBits=1+(value-265)/4;
WiredHome 63:ed787f5fcdc4 621 base=(8<<((value-265)/4))+3;
WiredHome 63:ed787f5fcdc4 622 offset=((value-265)&3)*(2<<((value-265)/4));
WiredHome 63:ed787f5fcdc4 623
WiredHome 63:ed787f5fcdc4 624 copyLength=GetNextMultiBit(dat,bytePtr,bitPtr,extBits);
WiredHome 63:ed787f5fcdc4 625 copyLength+=base+offset;
WiredHome 63:ed787f5fcdc4 626 }
WiredHome 63:ed787f5fcdc4 627
WiredHome 63:ed787f5fcdc4 628 return copyLength;
WiredHome 63:ed787f5fcdc4 629 }
WiredHome 63:ed787f5fcdc4 630
WiredHome 63:ed787f5fcdc4 631 unsigned YsPngUncompressor::GetBackwardDistance
WiredHome 63:ed787f5fcdc4 632 (unsigned distCode,unsigned char dat[],unsigned &bytePtr,unsigned &bitPtr)
WiredHome 63:ed787f5fcdc4 633 {
WiredHome 63:ed787f5fcdc4 634 unsigned backDist;
WiredHome 63:ed787f5fcdc4 635
WiredHome 63:ed787f5fcdc4 636 if(distCode<=3)
WiredHome 63:ed787f5fcdc4 637 {
WiredHome 63:ed787f5fcdc4 638 backDist=distCode+1;
WiredHome 63:ed787f5fcdc4 639 }
WiredHome 63:ed787f5fcdc4 640 else
WiredHome 63:ed787f5fcdc4 641 {
WiredHome 63:ed787f5fcdc4 642 unsigned base,offset,extBits;
WiredHome 63:ed787f5fcdc4 643
WiredHome 63:ed787f5fcdc4 644 base=(4<<((distCode-4)/2))+1;
WiredHome 63:ed787f5fcdc4 645 offset=(distCode&1)*(2<<((distCode-4)/2));
WiredHome 63:ed787f5fcdc4 646 extBits=(distCode-2)/2;
WiredHome 63:ed787f5fcdc4 647
WiredHome 63:ed787f5fcdc4 648 backDist=GetNextMultiBit(dat,bytePtr,bitPtr,extBits);
WiredHome 63:ed787f5fcdc4 649 backDist+=base+offset;
WiredHome 63:ed787f5fcdc4 650 }
WiredHome 63:ed787f5fcdc4 651
WiredHome 63:ed787f5fcdc4 652 return backDist;
WiredHome 63:ed787f5fcdc4 653 }
WiredHome 63:ed787f5fcdc4 654
WiredHome 63:ed787f5fcdc4 655 int YsPngUncompressor::Uncompress(unsigned length,unsigned char dat[])
WiredHome 63:ed787f5fcdc4 656 {
WiredHome 63:ed787f5fcdc4 657 unsigned windowUsed;
WiredHome 63:ed787f5fcdc4 658 //unsigned char *windowBuf;
WiredHome 63:ed787f5fcdc4 659 unsigned nByteExtracted;
WiredHome 63:ed787f5fcdc4 660 //windowBuf=NULL;
WiredHome 63:ed787f5fcdc4 661 SlidingWindow * windowBuf = NULL;
WiredHome 63:ed787f5fcdc4 662
WiredHome 63:ed787f5fcdc4 663 unsigned bytePtr,bitPtr;
WiredHome 63:ed787f5fcdc4 664 bytePtr=0;
WiredHome 63:ed787f5fcdc4 665 bitPtr=1;
WiredHome 63:ed787f5fcdc4 666 nByteExtracted=0;
WiredHome 63:ed787f5fcdc4 667
WiredHome 63:ed787f5fcdc4 668 //DSTrackClear();
WiredHome 63:ed787f5fcdc4 669 INFO("Begin zLib block length=%d bytePtr=%d bitPtr=0x%02x",length,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 670
WiredHome 63:ed787f5fcdc4 671 unsigned char cmf,flg;
WiredHome 63:ed787f5fcdc4 672 cmf=dat[bytePtr++];
WiredHome 63:ed787f5fcdc4 673 flg=dat[bytePtr++];
WiredHome 63:ed787f5fcdc4 674
WiredHome 63:ed787f5fcdc4 675 unsigned cm,cInfo,windowSize;
WiredHome 63:ed787f5fcdc4 676 cm=cmf&0x0f;
WiredHome 63:ed787f5fcdc4 677 if(cm!=8)
WiredHome 63:ed787f5fcdc4 678 {
WiredHome 63:ed787f5fcdc4 679 ERR("Unsupported compression method! (%d)",cm);
WiredHome 63:ed787f5fcdc4 680 goto ERREND;
WiredHome 63:ed787f5fcdc4 681 }
WiredHome 63:ed787f5fcdc4 682
WiredHome 63:ed787f5fcdc4 683 cInfo=(cmf&0xf0)>>4;
WiredHome 63:ed787f5fcdc4 684 windowSize=1<<(cInfo+8);
WiredHome 63:ed787f5fcdc4 685
WiredHome 63:ed787f5fcdc4 686 INFO("cInfo=%d, Window Size=%d",cInfo,windowSize);
WiredHome 63:ed787f5fcdc4 687
WiredHome 63:ed787f5fcdc4 688 //windowBuf = new unsigned char [windowSize];
WiredHome 63:ed787f5fcdc4 689 //windowBuf = (unsigned char *) malloc(windowSize);
WiredHome 63:ed787f5fcdc4 690 windowBuf = new SlidingWindow(windowSize, 3000); // windowSize);
WiredHome 63:ed787f5fcdc4 691
WiredHome 63:ed787f5fcdc4 692 if (windowBuf->status() == SlidingWindow::outofmemory)
WiredHome 63:ed787f5fcdc4 693 goto ERREND;
WiredHome 63:ed787f5fcdc4 694
WiredHome 63:ed787f5fcdc4 695 windowUsed=0;
WiredHome 63:ed787f5fcdc4 696
WiredHome 63:ed787f5fcdc4 697
WiredHome 63:ed787f5fcdc4 698 unsigned fCheck,fDict,fLevel;
WiredHome 63:ed787f5fcdc4 699 fCheck=(flg&15);
WiredHome 63:ed787f5fcdc4 700 fDict=(flg&32)>>5;
WiredHome 63:ed787f5fcdc4 701 fLevel=(flg&192)>>6;
WiredHome 63:ed787f5fcdc4 702
WiredHome 63:ed787f5fcdc4 703 INFO("fCheck=%d fDict=%d fLevel=%d",fCheck,fDict,fLevel);
WiredHome 63:ed787f5fcdc4 704
WiredHome 63:ed787f5fcdc4 705 if(fDict!=0)
WiredHome 63:ed787f5fcdc4 706 {
WiredHome 63:ed787f5fcdc4 707 ERR("PNG is not supposed to have a preset dictionary.");
WiredHome 63:ed787f5fcdc4 708 goto ERREND;
WiredHome 63:ed787f5fcdc4 709 }
WiredHome 63:ed787f5fcdc4 710
WiredHome 63:ed787f5fcdc4 711
WiredHome 63:ed787f5fcdc4 712 YsPngHuffmanTree *codeTree,*codeTreePtr;
WiredHome 63:ed787f5fcdc4 713 YsPngHuffmanTree *distTree,*distTreePtr;
WiredHome 63:ed787f5fcdc4 714 codeTree=NULL;
WiredHome 63:ed787f5fcdc4 715 distTree=NULL;
WiredHome 63:ed787f5fcdc4 716
WiredHome 63:ed787f5fcdc4 717 while(1)
WiredHome 63:ed787f5fcdc4 718 {
WiredHome 63:ed787f5fcdc4 719 unsigned bFinal,bType;
WiredHome 63:ed787f5fcdc4 720
WiredHome 63:ed787f5fcdc4 721 bFinal=GetNextBit(dat,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 722 bType=GetNextMultiBit(dat,bytePtr,bitPtr,2);
WiredHome 63:ed787f5fcdc4 723
WiredHome 63:ed787f5fcdc4 724 if(bytePtr>=length)
WiredHome 63:ed787f5fcdc4 725 {
WiredHome 63:ed787f5fcdc4 726 ERR("Buffer overflow");
WiredHome 63:ed787f5fcdc4 727 goto ERREND;
WiredHome 63:ed787f5fcdc4 728 }
WiredHome 63:ed787f5fcdc4 729
WiredHome 63:ed787f5fcdc4 730 INFO("bFinal=%d bType=%d",bFinal,bType);
WiredHome 63:ed787f5fcdc4 731
WiredHome 63:ed787f5fcdc4 732 if(bType==0) // No Compression
WiredHome 63:ed787f5fcdc4 733 {
WiredHome 63:ed787f5fcdc4 734 unsigned len;
WiredHome 63:ed787f5fcdc4 735 if(bitPtr!=1)
WiredHome 63:ed787f5fcdc4 736 {
WiredHome 63:ed787f5fcdc4 737 bitPtr=1;
WiredHome 63:ed787f5fcdc4 738 bytePtr++;
WiredHome 63:ed787f5fcdc4 739 }
WiredHome 63:ed787f5fcdc4 740 if(bytePtr>=length)
WiredHome 63:ed787f5fcdc4 741 {
WiredHome 63:ed787f5fcdc4 742 ERR("Buffer overflow");
WiredHome 63:ed787f5fcdc4 743 goto ERREND;
WiredHome 63:ed787f5fcdc4 744 }
WiredHome 63:ed787f5fcdc4 745
WiredHome 63:ed787f5fcdc4 746 len=dat[bytePtr]+dat[bytePtr+1]*256;
WiredHome 63:ed787f5fcdc4 747 bytePtr+=4;
WiredHome 63:ed787f5fcdc4 748
WiredHome 63:ed787f5fcdc4 749 // Feed len bytes
WiredHome 63:ed787f5fcdc4 750 int i;
WiredHome 63:ed787f5fcdc4 751 for(i=0; i<len; i++) // 2010/02/08
WiredHome 63:ed787f5fcdc4 752 {
WiredHome 63:ed787f5fcdc4 753 output->Output(dat[bytePtr+i]);
WiredHome 63:ed787f5fcdc4 754 if (!windowBuf->set(windowUsed++, dat[bytePtr + i]))
WiredHome 63:ed787f5fcdc4 755 goto ERREND;
WiredHome 63:ed787f5fcdc4 756 }
WiredHome 63:ed787f5fcdc4 757 bytePtr+=len;
WiredHome 63:ed787f5fcdc4 758 }
WiredHome 63:ed787f5fcdc4 759 else if(bType==1 || bType==2)
WiredHome 63:ed787f5fcdc4 760 {
WiredHome 63:ed787f5fcdc4 761 INFO("bType: %d", bType);
WiredHome 63:ed787f5fcdc4 762 codeTree=NULL;
WiredHome 63:ed787f5fcdc4 763
WiredHome 63:ed787f5fcdc4 764 if(bType==1)
WiredHome 63:ed787f5fcdc4 765 {
WiredHome 63:ed787f5fcdc4 766 unsigned hLength[288],hCode[288];
WiredHome 63:ed787f5fcdc4 767 MakeFixedHuffmanCode(hLength,hCode);
WiredHome 63:ed787f5fcdc4 768 INFO(" created fixed huffman code");
WiredHome 63:ed787f5fcdc4 769 codeTree=MakeHuffmanTree(288,hLength,hCode);
WiredHome 63:ed787f5fcdc4 770 INFO(" created huffman tree");
WiredHome 63:ed787f5fcdc4 771 distTree=NULL;
WiredHome 63:ed787f5fcdc4 772 }
WiredHome 63:ed787f5fcdc4 773 else
WiredHome 63:ed787f5fcdc4 774 {
WiredHome 63:ed787f5fcdc4 775 unsigned hLit,hDist,hCLen;
WiredHome 63:ed787f5fcdc4 776 unsigned *hLengthLiteral,*hCodeLiteral;
WiredHome 63:ed787f5fcdc4 777 unsigned *hLengthDist,*hCodeDist;
WiredHome 63:ed787f5fcdc4 778 unsigned hLengthBuf[322],hCodeBuf[322];
WiredHome 63:ed787f5fcdc4 779
WiredHome 63:ed787f5fcdc4 780 DecodeDynamicHuffmanCode
WiredHome 63:ed787f5fcdc4 781 (hLit,hDist,hCLen,
WiredHome 63:ed787f5fcdc4 782 hLengthLiteral,hCodeLiteral,hLengthDist,hCodeDist,hLengthBuf,hCodeBuf,
WiredHome 63:ed787f5fcdc4 783 dat,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 784
WiredHome 63:ed787f5fcdc4 785 INFO("Making Huffman Tree");
WiredHome 63:ed787f5fcdc4 786 codeTree=MakeHuffmanTree(hLit+257,hLengthLiteral,hCodeLiteral);
WiredHome 63:ed787f5fcdc4 787 distTree=MakeHuffmanTree(hDist+1,hLengthDist,hCodeDist);
WiredHome 63:ed787f5fcdc4 788 }
WiredHome 63:ed787f5fcdc4 789
WiredHome 63:ed787f5fcdc4 790 INFO("Huffman table prepared");
WiredHome 63:ed787f5fcdc4 791
WiredHome 63:ed787f5fcdc4 792 codeTreePtr=codeTree;
WiredHome 63:ed787f5fcdc4 793 if(codeTree!=NULL)
WiredHome 63:ed787f5fcdc4 794 {
WiredHome 63:ed787f5fcdc4 795 while(1)
WiredHome 63:ed787f5fcdc4 796 {
WiredHome 63:ed787f5fcdc4 797 if(GetNextBit(dat,bytePtr,bitPtr))
WiredHome 63:ed787f5fcdc4 798 {
WiredHome 63:ed787f5fcdc4 799 codeTreePtr=codeTreePtr->one;
WiredHome 63:ed787f5fcdc4 800 }
WiredHome 63:ed787f5fcdc4 801 else
WiredHome 63:ed787f5fcdc4 802 {
WiredHome 63:ed787f5fcdc4 803 codeTreePtr=codeTreePtr->zero;
WiredHome 63:ed787f5fcdc4 804 }
WiredHome 63:ed787f5fcdc4 805
WiredHome 63:ed787f5fcdc4 806 if(codeTreePtr==NULL)
WiredHome 63:ed787f5fcdc4 807 {
WiredHome 63:ed787f5fcdc4 808 ERR("Huffman Decompression: Reached NULL node.");
WiredHome 63:ed787f5fcdc4 809 goto ERREND;
WiredHome 63:ed787f5fcdc4 810 }
WiredHome 63:ed787f5fcdc4 811
WiredHome 63:ed787f5fcdc4 812 if(codeTreePtr->zero==NULL && codeTreePtr->one==NULL)
WiredHome 63:ed787f5fcdc4 813 {
WiredHome 63:ed787f5fcdc4 814 // INFO("[%d]",codeTreePtr->dat);
WiredHome 63:ed787f5fcdc4 815
WiredHome 63:ed787f5fcdc4 816 unsigned value;
WiredHome 63:ed787f5fcdc4 817 value=codeTreePtr->dat;
WiredHome 63:ed787f5fcdc4 818 if(value<256)
WiredHome 63:ed787f5fcdc4 819 {
WiredHome 63:ed787f5fcdc4 820 // windowBuf[windowUsed++]=value;
WiredHome 63:ed787f5fcdc4 821 if (!windowBuf->set(windowUsed++, value))
WiredHome 63:ed787f5fcdc4 822 goto ERREND;
WiredHome 63:ed787f5fcdc4 823 //DSTrackMax(windowUsed-1);
WiredHome 63:ed787f5fcdc4 824 //windowUsed&=(windowSize-1);
WiredHome 63:ed787f5fcdc4 825 if(output->Output(value)!=YSOK)
WiredHome 63:ed787f5fcdc4 826 {
WiredHome 63:ed787f5fcdc4 827 goto ERREND;
WiredHome 63:ed787f5fcdc4 828 }
WiredHome 63:ed787f5fcdc4 829 nByteExtracted++;
WiredHome 63:ed787f5fcdc4 830 }
WiredHome 63:ed787f5fcdc4 831 else if(value==256)
WiredHome 63:ed787f5fcdc4 832 {
WiredHome 63:ed787f5fcdc4 833 break;
WiredHome 63:ed787f5fcdc4 834 }
WiredHome 63:ed787f5fcdc4 835 else if(value<=285)
WiredHome 63:ed787f5fcdc4 836 {
WiredHome 63:ed787f5fcdc4 837 unsigned copyLength,distCode,backDist;
WiredHome 63:ed787f5fcdc4 838 copyLength=GetCopyLength(value,dat,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 839 // INFO("CopyLength %d",copyLength);
WiredHome 63:ed787f5fcdc4 840
WiredHome 63:ed787f5fcdc4 841 if(bType==1)
WiredHome 63:ed787f5fcdc4 842 {
WiredHome 63:ed787f5fcdc4 843 distCode=16*GetNextBit(dat,bytePtr,bitPtr); // 5 bits fixed
WiredHome 63:ed787f5fcdc4 844 distCode+=8*GetNextBit(dat,bytePtr,bitPtr); // Reversed order
WiredHome 63:ed787f5fcdc4 845 distCode+=4*GetNextBit(dat,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 846 distCode+=2*GetNextBit(dat,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 847 distCode+= GetNextBit(dat,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 848 }
WiredHome 63:ed787f5fcdc4 849 else
WiredHome 63:ed787f5fcdc4 850 {
WiredHome 63:ed787f5fcdc4 851 distTreePtr=distTree;
WiredHome 63:ed787f5fcdc4 852 while(distTreePtr->zero!=NULL || distTreePtr->one!=NULL)
WiredHome 63:ed787f5fcdc4 853 {
WiredHome 63:ed787f5fcdc4 854 if(GetNextBit(dat,bytePtr,bitPtr))
WiredHome 63:ed787f5fcdc4 855 {
WiredHome 63:ed787f5fcdc4 856 distTreePtr=distTreePtr->one;
WiredHome 63:ed787f5fcdc4 857 }
WiredHome 63:ed787f5fcdc4 858 else
WiredHome 63:ed787f5fcdc4 859 {
WiredHome 63:ed787f5fcdc4 860 distTreePtr=distTreePtr->zero;
WiredHome 63:ed787f5fcdc4 861 }
WiredHome 63:ed787f5fcdc4 862 }
WiredHome 63:ed787f5fcdc4 863 distCode=distTreePtr->dat;
WiredHome 63:ed787f5fcdc4 864 }
WiredHome 63:ed787f5fcdc4 865 backDist=GetBackwardDistance(distCode,dat,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 866 // INFO("DistCode %d BackDist %d",distCode,backDist);
WiredHome 63:ed787f5fcdc4 867
WiredHome 63:ed787f5fcdc4 868
WiredHome 63:ed787f5fcdc4 869 unsigned i;
WiredHome 63:ed787f5fcdc4 870 for(i=0; i<copyLength; i++)
WiredHome 63:ed787f5fcdc4 871 {
WiredHome 63:ed787f5fcdc4 872 unsigned char dat;
WiredHome 63:ed787f5fcdc4 873 //dat=windowBuf[(windowUsed-backDist)&(windowSize-1)];
WiredHome 63:ed787f5fcdc4 874 dat = windowBuf->get(windowUsed, backDist);
WiredHome 63:ed787f5fcdc4 875 //DSTrackMax((windowUsed-backDist)&(windowSize-1));
WiredHome 63:ed787f5fcdc4 876 if(output->Output(dat)!=YSOK)
WiredHome 63:ed787f5fcdc4 877 {
WiredHome 63:ed787f5fcdc4 878 goto ERREND;
WiredHome 63:ed787f5fcdc4 879 }
WiredHome 63:ed787f5fcdc4 880 nByteExtracted++;
WiredHome 63:ed787f5fcdc4 881 //windowBuf[windowUsed++]=dat;
WiredHome 63:ed787f5fcdc4 882 windowBuf->set(windowUsed++, dat);
WiredHome 63:ed787f5fcdc4 883 //DSTrackMax(windowUsed-1);
WiredHome 63:ed787f5fcdc4 884 //windowUsed&=(windowSize-1);
WiredHome 63:ed787f5fcdc4 885 }
WiredHome 63:ed787f5fcdc4 886 }
WiredHome 63:ed787f5fcdc4 887
WiredHome 63:ed787f5fcdc4 888 codeTreePtr=codeTree;
WiredHome 63:ed787f5fcdc4 889 }
WiredHome 63:ed787f5fcdc4 890
WiredHome 63:ed787f5fcdc4 891 if(length<=bytePtr)
WiredHome 63:ed787f5fcdc4 892 {
WiredHome 63:ed787f5fcdc4 893 goto ERREND;
WiredHome 63:ed787f5fcdc4 894 }
WiredHome 63:ed787f5fcdc4 895 }
WiredHome 63:ed787f5fcdc4 896 }
WiredHome 63:ed787f5fcdc4 897
WiredHome 63:ed787f5fcdc4 898
WiredHome 63:ed787f5fcdc4 899 DeleteHuffmanTree(codeTree);
WiredHome 63:ed787f5fcdc4 900 DeleteHuffmanTree(distTree);
WiredHome 63:ed787f5fcdc4 901 codeTree=NULL;
WiredHome 63:ed787f5fcdc4 902 distTree=NULL;
WiredHome 63:ed787f5fcdc4 903 }
WiredHome 63:ed787f5fcdc4 904 else
WiredHome 63:ed787f5fcdc4 905 {
WiredHome 63:ed787f5fcdc4 906 ERR("Unknown compression type (bType=3)");
WiredHome 63:ed787f5fcdc4 907 goto ERREND;
WiredHome 63:ed787f5fcdc4 908 }
WiredHome 63:ed787f5fcdc4 909
WiredHome 63:ed787f5fcdc4 910
WiredHome 63:ed787f5fcdc4 911 if(bFinal!=0)
WiredHome 63:ed787f5fcdc4 912 {
WiredHome 63:ed787f5fcdc4 913 break;
WiredHome 63:ed787f5fcdc4 914 }
WiredHome 63:ed787f5fcdc4 915 }
WiredHome 63:ed787f5fcdc4 916 //DSTrackReport();
WiredHome 63:ed787f5fcdc4 917 //delete [] windowBuf;
WiredHome 63:ed787f5fcdc4 918 //free(windowBuf);
WiredHome 63:ed787f5fcdc4 919 delete windowBuf;
WiredHome 63:ed787f5fcdc4 920 //windowBuf=NULL;
WiredHome 63:ed787f5fcdc4 921
WiredHome 63:ed787f5fcdc4 922 INFO("End zLib block length=%d bytePtr=%d bitPtr=0x%02x",length,bytePtr,bitPtr);
WiredHome 63:ed787f5fcdc4 923 INFO("Huffman Tree Leak Tracker = %d",YsPngHuffmanTree::leakTracker);
WiredHome 63:ed787f5fcdc4 924 INFO("Output %d bytes.",nByteExtracted);
WiredHome 63:ed787f5fcdc4 925
WiredHome 63:ed787f5fcdc4 926 return YSOK;
WiredHome 63:ed787f5fcdc4 927
WiredHome 63:ed787f5fcdc4 928 ERREND:
WiredHome 63:ed787f5fcdc4 929 ERR("ERREND:");
WiredHome 63:ed787f5fcdc4 930 if(windowBuf!=NULL)
WiredHome 63:ed787f5fcdc4 931 {
WiredHome 63:ed787f5fcdc4 932 //delete [] windowBuf;
WiredHome 63:ed787f5fcdc4 933 //free(windowBuf);
WiredHome 63:ed787f5fcdc4 934 delete windowBuf;
WiredHome 63:ed787f5fcdc4 935 }
WiredHome 63:ed787f5fcdc4 936 if(codeTree!=NULL)
WiredHome 63:ed787f5fcdc4 937 {
WiredHome 63:ed787f5fcdc4 938 DeleteHuffmanTree(codeTree);
WiredHome 63:ed787f5fcdc4 939 }
WiredHome 63:ed787f5fcdc4 940 if(distTree!=NULL)
WiredHome 63:ed787f5fcdc4 941 {
WiredHome 63:ed787f5fcdc4 942 DeleteHuffmanTree(distTree);
WiredHome 63:ed787f5fcdc4 943 }
WiredHome 63:ed787f5fcdc4 944 return YSERR;
WiredHome 63:ed787f5fcdc4 945 }
WiredHome 63:ed787f5fcdc4 946
WiredHome 63:ed787f5fcdc4 947 ////////////////////////////////////////////////////////////
WiredHome 63:ed787f5fcdc4 948
WiredHome 63:ed787f5fcdc4 949 int YsGenericPngDecoder::Decode(const char fn[])
WiredHome 63:ed787f5fcdc4 950 {
WiredHome 63:ed787f5fcdc4 951 FILE *fp;
WiredHome 63:ed787f5fcdc4 952 unsigned fileSize;
WiredHome 63:ed787f5fcdc4 953
WiredHome 63:ed787f5fcdc4 954 fp=fopen(fn,"rb");
WiredHome 63:ed787f5fcdc4 955 if(fp!=NULL)
WiredHome 63:ed787f5fcdc4 956 {
WiredHome 63:ed787f5fcdc4 957 fseek(fp,0,2 /* SEEK_END */);
WiredHome 63:ed787f5fcdc4 958 fileSize=ftell(fp);
WiredHome 63:ed787f5fcdc4 959 fseek(fp,0,0 /* SEEK_SET */);
WiredHome 63:ed787f5fcdc4 960
WiredHome 63:ed787f5fcdc4 961 if(CheckSignature(fp)!=YSOK)
WiredHome 63:ed787f5fcdc4 962 {
WiredHome 63:ed787f5fcdc4 963 ERR("The file does not have PNG signature.");
WiredHome 63:ed787f5fcdc4 964 goto ERREND;
WiredHome 63:ed787f5fcdc4 965 }
WiredHome 63:ed787f5fcdc4 966
WiredHome 63:ed787f5fcdc4 967 unsigned datBufUsed;
WiredHome 63:ed787f5fcdc4 968 unsigned char *datBuf;
WiredHome 63:ed787f5fcdc4 969
WiredHome 63:ed787f5fcdc4 970
WiredHome 63:ed787f5fcdc4 971 datBufUsed=0;
WiredHome 63:ed787f5fcdc4 972 datBuf = new unsigned char [fileSize];
WiredHome 63:ed787f5fcdc4 973
WiredHome 63:ed787f5fcdc4 974 INFO("datBuf allocated %d bytes", fileSize);
WiredHome 63:ed787f5fcdc4 975
WiredHome 63:ed787f5fcdc4 976 unsigned char *buf;
WiredHome 63:ed787f5fcdc4 977 unsigned length,chunkType,crc;
WiredHome 63:ed787f5fcdc4 978 while(ReadChunk(length,buf,chunkType,crc,fp)==YSOK && chunkType!=IEND)
WiredHome 63:ed787f5fcdc4 979 {
WiredHome 63:ed787f5fcdc4 980 switch(chunkType)
WiredHome 63:ed787f5fcdc4 981 {
WiredHome 63:ed787f5fcdc4 982 default:
WiredHome 63:ed787f5fcdc4 983 if(buf!=NULL)
WiredHome 63:ed787f5fcdc4 984 {
WiredHome 63:ed787f5fcdc4 985 delete [] buf;
WiredHome 63:ed787f5fcdc4 986 }
WiredHome 63:ed787f5fcdc4 987 break;
WiredHome 63:ed787f5fcdc4 988 case IHDR:
WiredHome 63:ed787f5fcdc4 989 if(buf!=NULL)
WiredHome 63:ed787f5fcdc4 990 {
WiredHome 63:ed787f5fcdc4 991 if(length>=13)
WiredHome 63:ed787f5fcdc4 992 {
WiredHome 63:ed787f5fcdc4 993 hdr.Decode(buf);
WiredHome 63:ed787f5fcdc4 994 }
WiredHome 63:ed787f5fcdc4 995 delete [] buf;
WiredHome 63:ed787f5fcdc4 996 }
WiredHome 63:ed787f5fcdc4 997 break;
WiredHome 63:ed787f5fcdc4 998 case PLTE:
WiredHome 63:ed787f5fcdc4 999 if(buf!=NULL)
WiredHome 63:ed787f5fcdc4 1000 {
WiredHome 63:ed787f5fcdc4 1001 if(plt.Decode(length,buf)!=YSOK)
WiredHome 63:ed787f5fcdc4 1002 {
WiredHome 63:ed787f5fcdc4 1003 delete [] buf;
WiredHome 63:ed787f5fcdc4 1004 goto ERREND;
WiredHome 63:ed787f5fcdc4 1005 }
WiredHome 63:ed787f5fcdc4 1006 delete [] buf;
WiredHome 63:ed787f5fcdc4 1007 }
WiredHome 63:ed787f5fcdc4 1008 break;
WiredHome 63:ed787f5fcdc4 1009 case tRNS:
WiredHome 63:ed787f5fcdc4 1010 if(buf!=NULL)
WiredHome 63:ed787f5fcdc4 1011 {
WiredHome 63:ed787f5fcdc4 1012 trns.Decode(length,buf,hdr.colorType);
WiredHome 63:ed787f5fcdc4 1013 delete [] buf;
WiredHome 63:ed787f5fcdc4 1014 }
WiredHome 63:ed787f5fcdc4 1015 break;
WiredHome 63:ed787f5fcdc4 1016 case gAMA:
WiredHome 63:ed787f5fcdc4 1017 if(buf!=NULL && length>=4)
WiredHome 63:ed787f5fcdc4 1018 {
WiredHome 63:ed787f5fcdc4 1019 gamma=PngGetUnsignedInt(buf);
WiredHome 63:ed787f5fcdc4 1020 INFO("Gamma %d (default=%d)",gamma,gamma_default);
WiredHome 63:ed787f5fcdc4 1021 delete [] buf;
WiredHome 63:ed787f5fcdc4 1022 }
WiredHome 63:ed787f5fcdc4 1023 break;
WiredHome 63:ed787f5fcdc4 1024 case IDAT:
WiredHome 63:ed787f5fcdc4 1025 if(buf!=NULL)
WiredHome 63:ed787f5fcdc4 1026 {
WiredHome 63:ed787f5fcdc4 1027 unsigned i;
WiredHome 63:ed787f5fcdc4 1028 for(i=0; i<length; i++)
WiredHome 63:ed787f5fcdc4 1029 {
WiredHome 63:ed787f5fcdc4 1030 datBuf[datBufUsed+i]=buf[i];
WiredHome 63:ed787f5fcdc4 1031 }
WiredHome 63:ed787f5fcdc4 1032 datBufUsed+=length;
WiredHome 63:ed787f5fcdc4 1033 delete [] buf;
WiredHome 63:ed787f5fcdc4 1034 }
WiredHome 63:ed787f5fcdc4 1035 }
WiredHome 63:ed787f5fcdc4 1036 }
WiredHome 63:ed787f5fcdc4 1037
WiredHome 63:ed787f5fcdc4 1038
WiredHome 63:ed787f5fcdc4 1039 if(PrepareOutput()==YSOK)
WiredHome 63:ed787f5fcdc4 1040 {
WiredHome 63:ed787f5fcdc4 1041 YsPngUncompressor uncompressor;
WiredHome 63:ed787f5fcdc4 1042 uncompressor.output=this;
WiredHome 63:ed787f5fcdc4 1043 uncompressor.Uncompress(datBufUsed,datBuf);
WiredHome 63:ed787f5fcdc4 1044 EndOutput();
WiredHome 63:ed787f5fcdc4 1045 }
WiredHome 63:ed787f5fcdc4 1046
WiredHome 63:ed787f5fcdc4 1047 delete [] datBuf;
WiredHome 63:ed787f5fcdc4 1048 fclose(fp);
WiredHome 63:ed787f5fcdc4 1049 return YSOK;
WiredHome 63:ed787f5fcdc4 1050 }
WiredHome 63:ed787f5fcdc4 1051
WiredHome 63:ed787f5fcdc4 1052 ERREND:
WiredHome 63:ed787f5fcdc4 1053 if(fp!=NULL)
WiredHome 63:ed787f5fcdc4 1054 {
WiredHome 63:ed787f5fcdc4 1055 fclose(fp);
WiredHome 63:ed787f5fcdc4 1056 }
WiredHome 63:ed787f5fcdc4 1057 return -1;
WiredHome 63:ed787f5fcdc4 1058 }
WiredHome 63:ed787f5fcdc4 1059
WiredHome 63:ed787f5fcdc4 1060 int YsGenericPngDecoder::PrepareOutput(void)
WiredHome 63:ed787f5fcdc4 1061 {
WiredHome 63:ed787f5fcdc4 1062 return YSOK;
WiredHome 63:ed787f5fcdc4 1063 }
WiredHome 63:ed787f5fcdc4 1064
WiredHome 63:ed787f5fcdc4 1065 int YsGenericPngDecoder::Output(unsigned char dat)
WiredHome 63:ed787f5fcdc4 1066 {
WiredHome 63:ed787f5fcdc4 1067 return YSOK;
WiredHome 63:ed787f5fcdc4 1068 }
WiredHome 63:ed787f5fcdc4 1069
WiredHome 63:ed787f5fcdc4 1070 int YsGenericPngDecoder::EndOutput(void)
WiredHome 63:ed787f5fcdc4 1071 {
WiredHome 63:ed787f5fcdc4 1072 return YSOK;
WiredHome 63:ed787f5fcdc4 1073 }
WiredHome 63:ed787f5fcdc4 1074
WiredHome 63:ed787f5fcdc4 1075
WiredHome 63:ed787f5fcdc4 1076
WiredHome 63:ed787f5fcdc4 1077 ////////////////////////////////////////////////////////////
WiredHome 63:ed787f5fcdc4 1078
WiredHome 63:ed787f5fcdc4 1079 static inline unsigned char Paeth(unsigned int ua,unsigned int ub,unsigned int uc)
WiredHome 63:ed787f5fcdc4 1080 {
WiredHome 63:ed787f5fcdc4 1081 int a,b,c,p,pa,pb,pc;
WiredHome 63:ed787f5fcdc4 1082
WiredHome 63:ed787f5fcdc4 1083 a=(int)ua;
WiredHome 63:ed787f5fcdc4 1084 b=(int)ub;
WiredHome 63:ed787f5fcdc4 1085 c=(int)uc;
WiredHome 63:ed787f5fcdc4 1086
WiredHome 63:ed787f5fcdc4 1087 p=a+b-c;
WiredHome 63:ed787f5fcdc4 1088 pa=(p>a ? p-a : a-p);
WiredHome 63:ed787f5fcdc4 1089 pb=(p>b ? p-b : b-p);
WiredHome 63:ed787f5fcdc4 1090 pc=(p>c ? p-c : c-p);
WiredHome 63:ed787f5fcdc4 1091
WiredHome 63:ed787f5fcdc4 1092 if(pa<=pb && pa<=pc)
WiredHome 63:ed787f5fcdc4 1093 {
WiredHome 63:ed787f5fcdc4 1094 return a;
WiredHome 63:ed787f5fcdc4 1095 }
WiredHome 63:ed787f5fcdc4 1096 else if(pb<=pc)
WiredHome 63:ed787f5fcdc4 1097 {
WiredHome 63:ed787f5fcdc4 1098 return b;
WiredHome 63:ed787f5fcdc4 1099 }
WiredHome 63:ed787f5fcdc4 1100 else
WiredHome 63:ed787f5fcdc4 1101 {
WiredHome 63:ed787f5fcdc4 1102 return c;
WiredHome 63:ed787f5fcdc4 1103 }
WiredHome 63:ed787f5fcdc4 1104 }
WiredHome 63:ed787f5fcdc4 1105
WiredHome 63:ed787f5fcdc4 1106 static inline void Filter8(unsigned char curLine[],unsigned char prvLine[],int x,int y,int unitLng,int filter)
WiredHome 63:ed787f5fcdc4 1107 {
WiredHome 63:ed787f5fcdc4 1108 int i;
WiredHome 63:ed787f5fcdc4 1109 switch(filter)
WiredHome 63:ed787f5fcdc4 1110 {
WiredHome 63:ed787f5fcdc4 1111 case 1:
WiredHome 63:ed787f5fcdc4 1112 if(x>0)
WiredHome 63:ed787f5fcdc4 1113 {
WiredHome 63:ed787f5fcdc4 1114 for(i=0; i<unitLng; i++)
WiredHome 63:ed787f5fcdc4 1115 {
WiredHome 63:ed787f5fcdc4 1116 curLine[x*unitLng+i]+=curLine[x*unitLng+i-unitLng];
WiredHome 63:ed787f5fcdc4 1117 }
WiredHome 63:ed787f5fcdc4 1118 }
WiredHome 63:ed787f5fcdc4 1119 break;
WiredHome 63:ed787f5fcdc4 1120 case 2:
WiredHome 63:ed787f5fcdc4 1121 if(y>0)
WiredHome 63:ed787f5fcdc4 1122 {
WiredHome 63:ed787f5fcdc4 1123 for(i=0; i<unitLng; i++)
WiredHome 63:ed787f5fcdc4 1124 {
WiredHome 63:ed787f5fcdc4 1125 curLine[x*unitLng+i]+=prvLine[x*unitLng+i];
WiredHome 63:ed787f5fcdc4 1126 }
WiredHome 63:ed787f5fcdc4 1127 }
WiredHome 63:ed787f5fcdc4 1128 break;
WiredHome 63:ed787f5fcdc4 1129 case 3:
WiredHome 63:ed787f5fcdc4 1130 for(i=0; i<unitLng; i++)
WiredHome 63:ed787f5fcdc4 1131 {
WiredHome 63:ed787f5fcdc4 1132 unsigned int a;
WiredHome 63:ed787f5fcdc4 1133 a=(x>0 ? curLine[x*unitLng+i-unitLng] : 0);
WiredHome 63:ed787f5fcdc4 1134 a+=(y>0 ? prvLine[x*unitLng+i] : 0);
WiredHome 63:ed787f5fcdc4 1135 curLine[x*unitLng+i]+=a/2;
WiredHome 63:ed787f5fcdc4 1136 }
WiredHome 63:ed787f5fcdc4 1137 break;
WiredHome 63:ed787f5fcdc4 1138 case 4:
WiredHome 63:ed787f5fcdc4 1139 for(i=0; i<unitLng; i++)
WiredHome 63:ed787f5fcdc4 1140 {
WiredHome 63:ed787f5fcdc4 1141 unsigned int a,b,c;
WiredHome 63:ed787f5fcdc4 1142 a=(x>0 ? curLine[x*unitLng+i-unitLng] : 0);
WiredHome 63:ed787f5fcdc4 1143 b=(y>0 ? prvLine[x*unitLng+i] : 0);
WiredHome 63:ed787f5fcdc4 1144 c=((x>0 && y>0) ? prvLine[x*unitLng-unitLng+i] : 0);
WiredHome 63:ed787f5fcdc4 1145 curLine[x*unitLng+i]+=Paeth(a,b,c);
WiredHome 63:ed787f5fcdc4 1146 }
WiredHome 63:ed787f5fcdc4 1147 break;
WiredHome 63:ed787f5fcdc4 1148 }
WiredHome 63:ed787f5fcdc4 1149 }
WiredHome 63:ed787f5fcdc4 1150
WiredHome 63:ed787f5fcdc4 1151 YsRawPngDecoder::YsRawPngDecoder()
WiredHome 63:ed787f5fcdc4 1152 {
WiredHome 63:ed787f5fcdc4 1153 wid=0;
WiredHome 63:ed787f5fcdc4 1154 hei=0;
WiredHome 63:ed787f5fcdc4 1155 rgba=NULL;
WiredHome 63:ed787f5fcdc4 1156 twoLineBuf8=NULL;
WiredHome 63:ed787f5fcdc4 1157
WiredHome 63:ed787f5fcdc4 1158 curLine8=NULL;
WiredHome 63:ed787f5fcdc4 1159 prvLine8=NULL;
WiredHome 63:ed787f5fcdc4 1160
WiredHome 63:ed787f5fcdc4 1161 autoDeleteRgbaBuffer=1;
WiredHome 63:ed787f5fcdc4 1162 }
WiredHome 63:ed787f5fcdc4 1163
WiredHome 63:ed787f5fcdc4 1164 YsRawPngDecoder::~YsRawPngDecoder()
WiredHome 63:ed787f5fcdc4 1165 {
WiredHome 63:ed787f5fcdc4 1166 if(autoDeleteRgbaBuffer==1 && rgba!=NULL)
WiredHome 63:ed787f5fcdc4 1167 {
WiredHome 63:ed787f5fcdc4 1168 delete [] rgba;
WiredHome 63:ed787f5fcdc4 1169 }
WiredHome 63:ed787f5fcdc4 1170 if(twoLineBuf8!=NULL)
WiredHome 63:ed787f5fcdc4 1171 {
WiredHome 63:ed787f5fcdc4 1172 delete [] twoLineBuf8;
WiredHome 63:ed787f5fcdc4 1173 }
WiredHome 63:ed787f5fcdc4 1174 }
WiredHome 63:ed787f5fcdc4 1175
WiredHome 63:ed787f5fcdc4 1176 void YsRawPngDecoder::ShiftTwoLineBuf(void)
WiredHome 63:ed787f5fcdc4 1177 {
WiredHome 63:ed787f5fcdc4 1178 if(twoLineBuf8!=NULL)
WiredHome 63:ed787f5fcdc4 1179 {
WiredHome 63:ed787f5fcdc4 1180 unsigned char *swap;
WiredHome 63:ed787f5fcdc4 1181 swap=curLine8;
WiredHome 63:ed787f5fcdc4 1182 curLine8=prvLine8;
WiredHome 63:ed787f5fcdc4 1183 prvLine8=swap;
WiredHome 63:ed787f5fcdc4 1184 }
WiredHome 63:ed787f5fcdc4 1185 }
WiredHome 63:ed787f5fcdc4 1186
WiredHome 63:ed787f5fcdc4 1187 int YsRawPngDecoder::PrepareOutput(void)
WiredHome 63:ed787f5fcdc4 1188 {
WiredHome 63:ed787f5fcdc4 1189 int supported;
WiredHome 63:ed787f5fcdc4 1190
WiredHome 63:ed787f5fcdc4 1191 supported=0;
WiredHome 63:ed787f5fcdc4 1192 switch(hdr.colorType)
WiredHome 63:ed787f5fcdc4 1193 {
WiredHome 63:ed787f5fcdc4 1194 case 0: // Greyscale
WiredHome 63:ed787f5fcdc4 1195 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1196 {
WiredHome 63:ed787f5fcdc4 1197 case 8:
WiredHome 63:ed787f5fcdc4 1198 case 1:
WiredHome 63:ed787f5fcdc4 1199 supported=1;
WiredHome 63:ed787f5fcdc4 1200 break;
WiredHome 63:ed787f5fcdc4 1201 case 2:
WiredHome 63:ed787f5fcdc4 1202 case 4:
WiredHome 63:ed787f5fcdc4 1203 case 16:
WiredHome 63:ed787f5fcdc4 1204 break;
WiredHome 63:ed787f5fcdc4 1205 }
WiredHome 63:ed787f5fcdc4 1206 break;
WiredHome 63:ed787f5fcdc4 1207 case 2: // Truecolor
WiredHome 63:ed787f5fcdc4 1208 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1209 {
WiredHome 63:ed787f5fcdc4 1210 case 8:
WiredHome 63:ed787f5fcdc4 1211 case 16:
WiredHome 63:ed787f5fcdc4 1212 supported=1;
WiredHome 63:ed787f5fcdc4 1213 break;
WiredHome 63:ed787f5fcdc4 1214 }
WiredHome 63:ed787f5fcdc4 1215 break;
WiredHome 63:ed787f5fcdc4 1216 case 3: // Indexed-color
WiredHome 63:ed787f5fcdc4 1217 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1218 {
WiredHome 63:ed787f5fcdc4 1219 case 4:
WiredHome 63:ed787f5fcdc4 1220 case 8:
WiredHome 63:ed787f5fcdc4 1221 supported=1;
WiredHome 63:ed787f5fcdc4 1222 break;
WiredHome 63:ed787f5fcdc4 1223 case 1:
WiredHome 63:ed787f5fcdc4 1224 case 2:
WiredHome 63:ed787f5fcdc4 1225 break;
WiredHome 63:ed787f5fcdc4 1226 }
WiredHome 63:ed787f5fcdc4 1227 break;
WiredHome 63:ed787f5fcdc4 1228 case 4: // Greyscale with alpha
WiredHome 63:ed787f5fcdc4 1229 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1230 {
WiredHome 63:ed787f5fcdc4 1231 case 8:
WiredHome 63:ed787f5fcdc4 1232 supported=1;
WiredHome 63:ed787f5fcdc4 1233 break;
WiredHome 63:ed787f5fcdc4 1234 case 16:
WiredHome 63:ed787f5fcdc4 1235 break;
WiredHome 63:ed787f5fcdc4 1236 }
WiredHome 63:ed787f5fcdc4 1237 break;
WiredHome 63:ed787f5fcdc4 1238 case 6: // Truecolor with alpha
WiredHome 63:ed787f5fcdc4 1239 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1240 {
WiredHome 63:ed787f5fcdc4 1241 case 8:
WiredHome 63:ed787f5fcdc4 1242 supported=1;
WiredHome 63:ed787f5fcdc4 1243 break;
WiredHome 63:ed787f5fcdc4 1244 case 16:
WiredHome 63:ed787f5fcdc4 1245 break;
WiredHome 63:ed787f5fcdc4 1246 }
WiredHome 63:ed787f5fcdc4 1247 break;
WiredHome 63:ed787f5fcdc4 1248 }
WiredHome 63:ed787f5fcdc4 1249
WiredHome 63:ed787f5fcdc4 1250 if(supported==0)
WiredHome 63:ed787f5fcdc4 1251 {
WiredHome 63:ed787f5fcdc4 1252 ERR("Unsupported colorType-bitDepth combination.");
WiredHome 63:ed787f5fcdc4 1253 return YSERR;
WiredHome 63:ed787f5fcdc4 1254 }
WiredHome 63:ed787f5fcdc4 1255
WiredHome 63:ed787f5fcdc4 1256
WiredHome 63:ed787f5fcdc4 1257
WiredHome 63:ed787f5fcdc4 1258 wid=hdr.width;
WiredHome 63:ed787f5fcdc4 1259 hei=hdr.height;
WiredHome 63:ed787f5fcdc4 1260 if(autoDeleteRgbaBuffer==1 && rgba!=NULL)
WiredHome 63:ed787f5fcdc4 1261 {
WiredHome 63:ed787f5fcdc4 1262 delete [] rgba;
WiredHome 63:ed787f5fcdc4 1263 rgba=NULL;
WiredHome 63:ed787f5fcdc4 1264 }
WiredHome 63:ed787f5fcdc4 1265 rgba=new unsigned char [wid*hei*4];
WiredHome 63:ed787f5fcdc4 1266 x=-1;
WiredHome 63:ed787f5fcdc4 1267 y=0;
WiredHome 63:ed787f5fcdc4 1268 filter=0;
WiredHome 63:ed787f5fcdc4 1269 inLineCount=0;
WiredHome 63:ed787f5fcdc4 1270 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1271 firstByte=1;
WiredHome 63:ed787f5fcdc4 1272 index=0;
WiredHome 63:ed787f5fcdc4 1273 interlacePass=1;
WiredHome 63:ed787f5fcdc4 1274
WiredHome 63:ed787f5fcdc4 1275 if(twoLineBuf8!=NULL)
WiredHome 63:ed787f5fcdc4 1276 {
WiredHome 63:ed787f5fcdc4 1277 delete [] twoLineBuf8;
WiredHome 63:ed787f5fcdc4 1278 twoLineBuf8=NULL;
WiredHome 63:ed787f5fcdc4 1279 }
WiredHome 63:ed787f5fcdc4 1280
WiredHome 63:ed787f5fcdc4 1281
WiredHome 63:ed787f5fcdc4 1282 // See PNG Specification 11.2 for Allowed combinations of color type and bit depth
WiredHome 63:ed787f5fcdc4 1283 unsigned int twoLineBufLngPerLine;
WiredHome 63:ed787f5fcdc4 1284 switch(hdr.colorType)
WiredHome 63:ed787f5fcdc4 1285 {
WiredHome 63:ed787f5fcdc4 1286 case 0: // Greyscale
WiredHome 63:ed787f5fcdc4 1287 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1288 {
WiredHome 63:ed787f5fcdc4 1289 case 1:
WiredHome 63:ed787f5fcdc4 1290 twoLineBufLngPerLine=(hdr.width+7)/8;
WiredHome 63:ed787f5fcdc4 1291 break;
WiredHome 63:ed787f5fcdc4 1292 case 2:
WiredHome 63:ed787f5fcdc4 1293 twoLineBufLngPerLine=(hdr.width+3)/4;
WiredHome 63:ed787f5fcdc4 1294 break;
WiredHome 63:ed787f5fcdc4 1295 case 4:
WiredHome 63:ed787f5fcdc4 1296 twoLineBufLngPerLine=(hdr.width+1)/2;
WiredHome 63:ed787f5fcdc4 1297 break;
WiredHome 63:ed787f5fcdc4 1298 case 8:
WiredHome 63:ed787f5fcdc4 1299 twoLineBufLngPerLine=hdr.width;
WiredHome 63:ed787f5fcdc4 1300 break;
WiredHome 63:ed787f5fcdc4 1301 case 16:
WiredHome 63:ed787f5fcdc4 1302 twoLineBufLngPerLine=hdr.width*2;
WiredHome 63:ed787f5fcdc4 1303 break;
WiredHome 63:ed787f5fcdc4 1304 }
WiredHome 63:ed787f5fcdc4 1305 break;
WiredHome 63:ed787f5fcdc4 1306 case 2: // Truecolor
WiredHome 63:ed787f5fcdc4 1307 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1308 {
WiredHome 63:ed787f5fcdc4 1309 case 8:
WiredHome 63:ed787f5fcdc4 1310 twoLineBufLngPerLine=hdr.width*3;
WiredHome 63:ed787f5fcdc4 1311 break;
WiredHome 63:ed787f5fcdc4 1312 case 16:
WiredHome 63:ed787f5fcdc4 1313 twoLineBufLngPerLine=hdr.width*6;
WiredHome 63:ed787f5fcdc4 1314 break;
WiredHome 63:ed787f5fcdc4 1315 }
WiredHome 63:ed787f5fcdc4 1316 break;
WiredHome 63:ed787f5fcdc4 1317 case 3: // Indexed-color
WiredHome 63:ed787f5fcdc4 1318 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1319 {
WiredHome 63:ed787f5fcdc4 1320 case 1:
WiredHome 63:ed787f5fcdc4 1321 twoLineBufLngPerLine=(hdr.width+7)/8;
WiredHome 63:ed787f5fcdc4 1322 break;
WiredHome 63:ed787f5fcdc4 1323 case 2:
WiredHome 63:ed787f5fcdc4 1324 twoLineBufLngPerLine=(hdr.width+3)/4;
WiredHome 63:ed787f5fcdc4 1325 break;
WiredHome 63:ed787f5fcdc4 1326 case 4:
WiredHome 63:ed787f5fcdc4 1327 twoLineBufLngPerLine=(hdr.width+1)/2;
WiredHome 63:ed787f5fcdc4 1328 break;
WiredHome 63:ed787f5fcdc4 1329 case 8:
WiredHome 63:ed787f5fcdc4 1330 twoLineBufLngPerLine=hdr.width;
WiredHome 63:ed787f5fcdc4 1331 break;
WiredHome 63:ed787f5fcdc4 1332 }
WiredHome 63:ed787f5fcdc4 1333 break;
WiredHome 63:ed787f5fcdc4 1334 case 4: // Greyscale with alpha
WiredHome 63:ed787f5fcdc4 1335 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1336 {
WiredHome 63:ed787f5fcdc4 1337 case 8:
WiredHome 63:ed787f5fcdc4 1338 twoLineBufLngPerLine=hdr.width*2;
WiredHome 63:ed787f5fcdc4 1339 break;
WiredHome 63:ed787f5fcdc4 1340 case 16:
WiredHome 63:ed787f5fcdc4 1341 twoLineBufLngPerLine=hdr.width*4;
WiredHome 63:ed787f5fcdc4 1342 break;
WiredHome 63:ed787f5fcdc4 1343 }
WiredHome 63:ed787f5fcdc4 1344 break;
WiredHome 63:ed787f5fcdc4 1345 case 6: // Truecolor with alpha
WiredHome 63:ed787f5fcdc4 1346 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1347 {
WiredHome 63:ed787f5fcdc4 1348 case 8:
WiredHome 63:ed787f5fcdc4 1349 twoLineBufLngPerLine=hdr.width*4;
WiredHome 63:ed787f5fcdc4 1350 break;
WiredHome 63:ed787f5fcdc4 1351 case 16:
WiredHome 63:ed787f5fcdc4 1352 twoLineBufLngPerLine=hdr.width*8;
WiredHome 63:ed787f5fcdc4 1353 break;
WiredHome 63:ed787f5fcdc4 1354 }
WiredHome 63:ed787f5fcdc4 1355 break;
WiredHome 63:ed787f5fcdc4 1356 }
WiredHome 63:ed787f5fcdc4 1357
WiredHome 63:ed787f5fcdc4 1358 twoLineBuf8=new unsigned char [twoLineBufLngPerLine*2];
WiredHome 63:ed787f5fcdc4 1359 curLine8=twoLineBuf8;
WiredHome 63:ed787f5fcdc4 1360 prvLine8=twoLineBuf8+twoLineBufLngPerLine;
WiredHome 63:ed787f5fcdc4 1361
WiredHome 63:ed787f5fcdc4 1362 return YSOK;
WiredHome 63:ed787f5fcdc4 1363 }
WiredHome 63:ed787f5fcdc4 1364
WiredHome 63:ed787f5fcdc4 1365 int YsRawPngDecoder::Output(unsigned char dat)
WiredHome 63:ed787f5fcdc4 1366 {
WiredHome 63:ed787f5fcdc4 1367 unsigned int i;
WiredHome 63:ed787f5fcdc4 1368 unsigned int colIdx;
WiredHome 63:ed787f5fcdc4 1369 unsigned int interlaceWid,interlaceHei,interlaceX,interlaceY;
WiredHome 63:ed787f5fcdc4 1370
WiredHome 63:ed787f5fcdc4 1371 if(y>=hei)
WiredHome 63:ed787f5fcdc4 1372 {
WiredHome 63:ed787f5fcdc4 1373 return YSERR;
WiredHome 63:ed787f5fcdc4 1374 }
WiredHome 63:ed787f5fcdc4 1375
WiredHome 63:ed787f5fcdc4 1376 if(x==-1) // First byte is filter type for the line.
WiredHome 63:ed787f5fcdc4 1377 {
WiredHome 63:ed787f5fcdc4 1378 filter=dat; // See PNG Specification 4.5.4 Filtering, 9 Filtering
WiredHome 63:ed787f5fcdc4 1379 inLineCount=0;
WiredHome 63:ed787f5fcdc4 1380 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1381 x++;
WiredHome 63:ed787f5fcdc4 1382 // INFO("y=%d filter=%d",y,filter);
WiredHome 63:ed787f5fcdc4 1383 return YSOK;
WiredHome 63:ed787f5fcdc4 1384 }
WiredHome 63:ed787f5fcdc4 1385 else
WiredHome 63:ed787f5fcdc4 1386 {
WiredHome 63:ed787f5fcdc4 1387 switch(hdr.interlaceMethod)
WiredHome 63:ed787f5fcdc4 1388 {
WiredHome 63:ed787f5fcdc4 1389 // Non-Interlace
WiredHome 63:ed787f5fcdc4 1390 case 0:
WiredHome 63:ed787f5fcdc4 1391 switch(hdr.colorType) // See PNG Specification 6.1 Colour types and values
WiredHome 63:ed787f5fcdc4 1392 {
WiredHome 63:ed787f5fcdc4 1393 // Grayscale
WiredHome 63:ed787f5fcdc4 1394 case 0:
WiredHome 63:ed787f5fcdc4 1395 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1396 {
WiredHome 63:ed787f5fcdc4 1397 case 1:
WiredHome 63:ed787f5fcdc4 1398 curLine8[x/8]=dat;
WiredHome 63:ed787f5fcdc4 1399 Filter8(curLine8,prvLine8,x/8,y,1,filter);
WiredHome 63:ed787f5fcdc4 1400
WiredHome 63:ed787f5fcdc4 1401 for(i=0; i<8 && x<wid; i++)
WiredHome 63:ed787f5fcdc4 1402 {
WiredHome 63:ed787f5fcdc4 1403 colIdx=(curLine8[x/8]>>(7-i))&1;
WiredHome 63:ed787f5fcdc4 1404 colIdx=(colIdx<<1)+colIdx;
WiredHome 63:ed787f5fcdc4 1405 colIdx=(colIdx<<2)+colIdx;
WiredHome 63:ed787f5fcdc4 1406 colIdx=(colIdx<<4)+colIdx;
WiredHome 63:ed787f5fcdc4 1407
WiredHome 63:ed787f5fcdc4 1408 rgba[index ]=colIdx;
WiredHome 63:ed787f5fcdc4 1409 rgba[index+1]=colIdx;
WiredHome 63:ed787f5fcdc4 1410 rgba[index+2]=colIdx;
WiredHome 63:ed787f5fcdc4 1411 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1412 x++;
WiredHome 63:ed787f5fcdc4 1413 index+=4;
WiredHome 63:ed787f5fcdc4 1414 }
WiredHome 63:ed787f5fcdc4 1415 break;
WiredHome 63:ed787f5fcdc4 1416
WiredHome 63:ed787f5fcdc4 1417 case 8:
WiredHome 63:ed787f5fcdc4 1418 curLine8[x]=dat;
WiredHome 63:ed787f5fcdc4 1419 Filter8(curLine8,prvLine8,x,y,1,filter);
WiredHome 63:ed787f5fcdc4 1420 colIdx=curLine8[x];
WiredHome 63:ed787f5fcdc4 1421
WiredHome 63:ed787f5fcdc4 1422 rgba[index ]=curLine8[x];
WiredHome 63:ed787f5fcdc4 1423 rgba[index+1]=curLine8[x];
WiredHome 63:ed787f5fcdc4 1424 rgba[index+2]=curLine8[x];
WiredHome 63:ed787f5fcdc4 1425 if(curLine8[x]==trns.col[0] || curLine8[x]==trns.col[1] || curLine8[x]==trns.col[2])
WiredHome 63:ed787f5fcdc4 1426 {
WiredHome 63:ed787f5fcdc4 1427 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1428 }
WiredHome 63:ed787f5fcdc4 1429 else
WiredHome 63:ed787f5fcdc4 1430 {
WiredHome 63:ed787f5fcdc4 1431 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1432 }
WiredHome 63:ed787f5fcdc4 1433
WiredHome 63:ed787f5fcdc4 1434 x++;
WiredHome 63:ed787f5fcdc4 1435 index+=4;
WiredHome 63:ed787f5fcdc4 1436 break;
WiredHome 63:ed787f5fcdc4 1437 }
WiredHome 63:ed787f5fcdc4 1438 break;
WiredHome 63:ed787f5fcdc4 1439
WiredHome 63:ed787f5fcdc4 1440
WiredHome 63:ed787f5fcdc4 1441
WiredHome 63:ed787f5fcdc4 1442 // True color
WiredHome 63:ed787f5fcdc4 1443 case 2:
WiredHome 63:ed787f5fcdc4 1444 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1445 {
WiredHome 63:ed787f5fcdc4 1446 case 8:
WiredHome 63:ed787f5fcdc4 1447 curLine8[inLineCount+inPixelCount]=dat;
WiredHome 63:ed787f5fcdc4 1448 inPixelCount++;
WiredHome 63:ed787f5fcdc4 1449 if(inPixelCount==3)
WiredHome 63:ed787f5fcdc4 1450 {
WiredHome 63:ed787f5fcdc4 1451 Filter8(curLine8,prvLine8,x,y,3,filter);
WiredHome 63:ed787f5fcdc4 1452 rgba[index ]=curLine8[inLineCount];
WiredHome 63:ed787f5fcdc4 1453 rgba[index+1]=curLine8[inLineCount+1];
WiredHome 63:ed787f5fcdc4 1454 rgba[index+2]=curLine8[inLineCount+2];
WiredHome 63:ed787f5fcdc4 1455
WiredHome 63:ed787f5fcdc4 1456 if(curLine8[inLineCount ]==trns.col[0] &&
WiredHome 63:ed787f5fcdc4 1457 curLine8[inLineCount+1]==trns.col[1] &&
WiredHome 63:ed787f5fcdc4 1458 curLine8[inLineCount+2]==trns.col[2])
WiredHome 63:ed787f5fcdc4 1459 {
WiredHome 63:ed787f5fcdc4 1460 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1461 }
WiredHome 63:ed787f5fcdc4 1462 else
WiredHome 63:ed787f5fcdc4 1463 {
WiredHome 63:ed787f5fcdc4 1464 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1465 }
WiredHome 63:ed787f5fcdc4 1466
WiredHome 63:ed787f5fcdc4 1467 x++;
WiredHome 63:ed787f5fcdc4 1468 index+=4;
WiredHome 63:ed787f5fcdc4 1469 inLineCount+=3;
WiredHome 63:ed787f5fcdc4 1470 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1471 }
WiredHome 63:ed787f5fcdc4 1472 break;
WiredHome 63:ed787f5fcdc4 1473 case 16:
WiredHome 63:ed787f5fcdc4 1474 curLine8[inLineCount+inPixelCount]=dat;
WiredHome 63:ed787f5fcdc4 1475 inPixelCount++;
WiredHome 63:ed787f5fcdc4 1476 if(inPixelCount==6)
WiredHome 63:ed787f5fcdc4 1477 {
WiredHome 63:ed787f5fcdc4 1478 Filter8(curLine8,prvLine8,x,y,6,filter);
WiredHome 63:ed787f5fcdc4 1479 rgba[index ]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1480 rgba[index+1]=curLine8[inLineCount+2];
WiredHome 63:ed787f5fcdc4 1481 rgba[index+2]=curLine8[inLineCount+4];
WiredHome 63:ed787f5fcdc4 1482
WiredHome 63:ed787f5fcdc4 1483 r=curLine8[inLineCount ]*256+curLine8[inLineCount+1];
WiredHome 63:ed787f5fcdc4 1484 g=curLine8[inLineCount+2]*256+curLine8[inLineCount+3];
WiredHome 63:ed787f5fcdc4 1485 b=curLine8[inLineCount+4]*256+curLine8[inLineCount+5];
WiredHome 63:ed787f5fcdc4 1486 if(r==trns.col[0] && g==trns.col[1] && b==trns.col[2])
WiredHome 63:ed787f5fcdc4 1487 {
WiredHome 63:ed787f5fcdc4 1488 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1489 }
WiredHome 63:ed787f5fcdc4 1490 else
WiredHome 63:ed787f5fcdc4 1491 {
WiredHome 63:ed787f5fcdc4 1492 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1493 }
WiredHome 63:ed787f5fcdc4 1494 x++;
WiredHome 63:ed787f5fcdc4 1495 index+=4;
WiredHome 63:ed787f5fcdc4 1496 inLineCount+=6;
WiredHome 63:ed787f5fcdc4 1497 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1498 }
WiredHome 63:ed787f5fcdc4 1499 break;
WiredHome 63:ed787f5fcdc4 1500 }
WiredHome 63:ed787f5fcdc4 1501 break;
WiredHome 63:ed787f5fcdc4 1502
WiredHome 63:ed787f5fcdc4 1503
WiredHome 63:ed787f5fcdc4 1504
WiredHome 63:ed787f5fcdc4 1505 // Indexed color
WiredHome 63:ed787f5fcdc4 1506 case 3:
WiredHome 63:ed787f5fcdc4 1507 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1508 {
WiredHome 63:ed787f5fcdc4 1509 case 4:
WiredHome 63:ed787f5fcdc4 1510 curLine8[x/2]=dat;
WiredHome 63:ed787f5fcdc4 1511 Filter8(curLine8,prvLine8,x/2,y,1,filter);
WiredHome 63:ed787f5fcdc4 1512
WiredHome 63:ed787f5fcdc4 1513 for(i=0; i<2 && x<wid; i++)
WiredHome 63:ed787f5fcdc4 1514 {
WiredHome 63:ed787f5fcdc4 1515 colIdx=(curLine8[x/2]>>((1-i)*4))&0x0f;
WiredHome 63:ed787f5fcdc4 1516
WiredHome 63:ed787f5fcdc4 1517 if(colIdx<plt.nEntry)
WiredHome 63:ed787f5fcdc4 1518 {
WiredHome 63:ed787f5fcdc4 1519 rgba[index ]=plt.entry[colIdx*3 ];
WiredHome 63:ed787f5fcdc4 1520 rgba[index+1]=plt.entry[colIdx*3+1];
WiredHome 63:ed787f5fcdc4 1521 rgba[index+2]=plt.entry[colIdx*3+2];
WiredHome 63:ed787f5fcdc4 1522 if(colIdx==trns.col[0] || colIdx==trns.col[1] || colIdx==trns.col[2])
WiredHome 63:ed787f5fcdc4 1523 {
WiredHome 63:ed787f5fcdc4 1524 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1525 }
WiredHome 63:ed787f5fcdc4 1526 else
WiredHome 63:ed787f5fcdc4 1527 {
WiredHome 63:ed787f5fcdc4 1528 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1529 }
WiredHome 63:ed787f5fcdc4 1530 }
WiredHome 63:ed787f5fcdc4 1531 x++;
WiredHome 63:ed787f5fcdc4 1532 index+=4;
WiredHome 63:ed787f5fcdc4 1533 }
WiredHome 63:ed787f5fcdc4 1534 break;
WiredHome 63:ed787f5fcdc4 1535
WiredHome 63:ed787f5fcdc4 1536 case 8:
WiredHome 63:ed787f5fcdc4 1537 curLine8[x]=dat;
WiredHome 63:ed787f5fcdc4 1538 Filter8(curLine8,prvLine8,x,y,1,filter);
WiredHome 63:ed787f5fcdc4 1539 colIdx=curLine8[x];
WiredHome 63:ed787f5fcdc4 1540
WiredHome 63:ed787f5fcdc4 1541 if(colIdx<plt.nEntry)
WiredHome 63:ed787f5fcdc4 1542 {
WiredHome 63:ed787f5fcdc4 1543 rgba[index ]=plt.entry[colIdx*3 ];
WiredHome 63:ed787f5fcdc4 1544 rgba[index+1]=plt.entry[colIdx*3+1];
WiredHome 63:ed787f5fcdc4 1545 rgba[index+2]=plt.entry[colIdx*3+2];
WiredHome 63:ed787f5fcdc4 1546 if(colIdx==trns.col[0] || colIdx==trns.col[1] || colIdx==trns.col[2])
WiredHome 63:ed787f5fcdc4 1547 {
WiredHome 63:ed787f5fcdc4 1548 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1549 }
WiredHome 63:ed787f5fcdc4 1550 else
WiredHome 63:ed787f5fcdc4 1551 {
WiredHome 63:ed787f5fcdc4 1552 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1553 }
WiredHome 63:ed787f5fcdc4 1554 }
WiredHome 63:ed787f5fcdc4 1555 x++;
WiredHome 63:ed787f5fcdc4 1556 index+=4;
WiredHome 63:ed787f5fcdc4 1557 break;
WiredHome 63:ed787f5fcdc4 1558 }
WiredHome 63:ed787f5fcdc4 1559 break;
WiredHome 63:ed787f5fcdc4 1560
WiredHome 63:ed787f5fcdc4 1561
WiredHome 63:ed787f5fcdc4 1562
WiredHome 63:ed787f5fcdc4 1563 // Greyscale with alpha
WiredHome 63:ed787f5fcdc4 1564 case 4:
WiredHome 63:ed787f5fcdc4 1565 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1566 {
WiredHome 63:ed787f5fcdc4 1567 case 8:
WiredHome 63:ed787f5fcdc4 1568 curLine8[inLineCount+inPixelCount]=dat;
WiredHome 63:ed787f5fcdc4 1569 inPixelCount++;
WiredHome 63:ed787f5fcdc4 1570 if(inPixelCount==2)
WiredHome 63:ed787f5fcdc4 1571 {
WiredHome 63:ed787f5fcdc4 1572 Filter8(curLine8,prvLine8,x,y,2,filter);
WiredHome 63:ed787f5fcdc4 1573 rgba[index ]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1574 rgba[index+1]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1575 rgba[index+2]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1576 rgba[index+3]=curLine8[inLineCount+1];
WiredHome 63:ed787f5fcdc4 1577 index+=4;
WiredHome 63:ed787f5fcdc4 1578 x++;
WiredHome 63:ed787f5fcdc4 1579 inLineCount+=2;
WiredHome 63:ed787f5fcdc4 1580 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1581 }
WiredHome 63:ed787f5fcdc4 1582 break;
WiredHome 63:ed787f5fcdc4 1583 }
WiredHome 63:ed787f5fcdc4 1584 break;
WiredHome 63:ed787f5fcdc4 1585
WiredHome 63:ed787f5fcdc4 1586
WiredHome 63:ed787f5fcdc4 1587
WiredHome 63:ed787f5fcdc4 1588 // Truecolor with alpha
WiredHome 63:ed787f5fcdc4 1589 case 6:
WiredHome 63:ed787f5fcdc4 1590 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1591 {
WiredHome 63:ed787f5fcdc4 1592 case 8:
WiredHome 63:ed787f5fcdc4 1593 curLine8[inLineCount+inPixelCount]=dat;
WiredHome 63:ed787f5fcdc4 1594 inPixelCount++;
WiredHome 63:ed787f5fcdc4 1595 if(inPixelCount==4)
WiredHome 63:ed787f5fcdc4 1596 {
WiredHome 63:ed787f5fcdc4 1597 Filter8(curLine8,prvLine8,x,y,4,filter);
WiredHome 63:ed787f5fcdc4 1598 rgba[index ]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1599 rgba[index+1]=curLine8[inLineCount+1];
WiredHome 63:ed787f5fcdc4 1600 rgba[index+2]=curLine8[inLineCount+2];
WiredHome 63:ed787f5fcdc4 1601 rgba[index+3]=curLine8[inLineCount+3];
WiredHome 63:ed787f5fcdc4 1602 index+=4;
WiredHome 63:ed787f5fcdc4 1603 x++;
WiredHome 63:ed787f5fcdc4 1604 inLineCount+=4;
WiredHome 63:ed787f5fcdc4 1605 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1606 }
WiredHome 63:ed787f5fcdc4 1607 break;
WiredHome 63:ed787f5fcdc4 1608 }
WiredHome 63:ed787f5fcdc4 1609 break;
WiredHome 63:ed787f5fcdc4 1610 } // switch(hdr.colorType)
WiredHome 63:ed787f5fcdc4 1611
WiredHome 63:ed787f5fcdc4 1612 if(x>=wid)
WiredHome 63:ed787f5fcdc4 1613 {
WiredHome 63:ed787f5fcdc4 1614 y++;
WiredHome 63:ed787f5fcdc4 1615 x=-1;
WiredHome 63:ed787f5fcdc4 1616 ShiftTwoLineBuf();
WiredHome 63:ed787f5fcdc4 1617 }
WiredHome 63:ed787f5fcdc4 1618
WiredHome 63:ed787f5fcdc4 1619 return YSOK;
WiredHome 63:ed787f5fcdc4 1620
WiredHome 63:ed787f5fcdc4 1621
WiredHome 63:ed787f5fcdc4 1622 // Interlace
WiredHome 63:ed787f5fcdc4 1623 case 1:
WiredHome 63:ed787f5fcdc4 1624 // 1 6 4 6 2 6 4 6
WiredHome 63:ed787f5fcdc4 1625 // 7 7 7 7 7 7 7 7
WiredHome 63:ed787f5fcdc4 1626 // 5 6 5 6 5 6 5 6
WiredHome 63:ed787f5fcdc4 1627 // 7 7 7 7 7 7 7 7
WiredHome 63:ed787f5fcdc4 1628 // 3 6 4 6 3 6 4 6
WiredHome 63:ed787f5fcdc4 1629 // 7 7 7 7 7 7 7 7
WiredHome 63:ed787f5fcdc4 1630 // 5 6 5 6 5 6 5 6
WiredHome 63:ed787f5fcdc4 1631 // 7 7 7 7 7 7 7 7
WiredHome 63:ed787f5fcdc4 1632 switch(interlacePass)
WiredHome 63:ed787f5fcdc4 1633 {
WiredHome 63:ed787f5fcdc4 1634 case 1:
WiredHome 63:ed787f5fcdc4 1635 interlaceWid=(wid+7)/8;
WiredHome 63:ed787f5fcdc4 1636 interlaceHei=(hei+7)/8;
WiredHome 63:ed787f5fcdc4 1637 interlaceX=x*8;
WiredHome 63:ed787f5fcdc4 1638 interlaceY=y*8;
WiredHome 63:ed787f5fcdc4 1639 break;
WiredHome 63:ed787f5fcdc4 1640 case 2:
WiredHome 63:ed787f5fcdc4 1641 interlaceWid=(wid+3)/8;
WiredHome 63:ed787f5fcdc4 1642 interlaceHei=(hei+7)/8;
WiredHome 63:ed787f5fcdc4 1643 interlaceX=4+x*8;
WiredHome 63:ed787f5fcdc4 1644 interlaceY=y*8;
WiredHome 63:ed787f5fcdc4 1645 break;
WiredHome 63:ed787f5fcdc4 1646 case 3:
WiredHome 63:ed787f5fcdc4 1647 interlaceWid=(wid+3)/4;
WiredHome 63:ed787f5fcdc4 1648 interlaceHei=(hei+3)/8;
WiredHome 63:ed787f5fcdc4 1649 interlaceX=x*4;
WiredHome 63:ed787f5fcdc4 1650 interlaceY=4+y*8;
WiredHome 63:ed787f5fcdc4 1651 break;
WiredHome 63:ed787f5fcdc4 1652 case 4:
WiredHome 63:ed787f5fcdc4 1653 interlaceWid=(wid+1)/4;
WiredHome 63:ed787f5fcdc4 1654 interlaceHei=(hei+3)/4;
WiredHome 63:ed787f5fcdc4 1655 interlaceX=2+x*4;
WiredHome 63:ed787f5fcdc4 1656 interlaceY=y*4;
WiredHome 63:ed787f5fcdc4 1657 break;
WiredHome 63:ed787f5fcdc4 1658 case 5:
WiredHome 63:ed787f5fcdc4 1659 interlaceWid=(wid+1)/2;
WiredHome 63:ed787f5fcdc4 1660 interlaceHei=(hei+1)/4;
WiredHome 63:ed787f5fcdc4 1661 interlaceX=x*2;
WiredHome 63:ed787f5fcdc4 1662 interlaceY=2+y*4;
WiredHome 63:ed787f5fcdc4 1663 break;
WiredHome 63:ed787f5fcdc4 1664 case 6:
WiredHome 63:ed787f5fcdc4 1665 interlaceWid=(wid )/2;
WiredHome 63:ed787f5fcdc4 1666 interlaceHei=(hei+1)/2;
WiredHome 63:ed787f5fcdc4 1667 interlaceX=1+x*2;
WiredHome 63:ed787f5fcdc4 1668 interlaceY=y*2;
WiredHome 63:ed787f5fcdc4 1669 break;
WiredHome 63:ed787f5fcdc4 1670 case 7:
WiredHome 63:ed787f5fcdc4 1671 interlaceWid=wid;
WiredHome 63:ed787f5fcdc4 1672 interlaceHei=hei/2;
WiredHome 63:ed787f5fcdc4 1673 interlaceX=x;
WiredHome 63:ed787f5fcdc4 1674 interlaceY=1+y*2;
WiredHome 63:ed787f5fcdc4 1675 break;
WiredHome 63:ed787f5fcdc4 1676 default:
WiredHome 63:ed787f5fcdc4 1677 return YSERR;
WiredHome 63:ed787f5fcdc4 1678 } // switch(interlacePass)
WiredHome 63:ed787f5fcdc4 1679
WiredHome 63:ed787f5fcdc4 1680 switch(hdr.colorType) // See PNG Specification 6.1 Colour types and values
WiredHome 63:ed787f5fcdc4 1681 {
WiredHome 63:ed787f5fcdc4 1682 // Grayscale
WiredHome 63:ed787f5fcdc4 1683 case 0:
WiredHome 63:ed787f5fcdc4 1684 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1685 {
WiredHome 63:ed787f5fcdc4 1686 case 8:
WiredHome 63:ed787f5fcdc4 1687 curLine8[inLineCount]=dat;
WiredHome 63:ed787f5fcdc4 1688 Filter8(curLine8,prvLine8,x,y,1,filter);
WiredHome 63:ed787f5fcdc4 1689
WiredHome 63:ed787f5fcdc4 1690 index=interlaceX*4+interlaceY*wid*4;
WiredHome 63:ed787f5fcdc4 1691 rgba[index ]=curLine8[inLineCount];
WiredHome 63:ed787f5fcdc4 1692 rgba[index+1]=curLine8[inLineCount];
WiredHome 63:ed787f5fcdc4 1693 rgba[index+2]=curLine8[inLineCount];
WiredHome 63:ed787f5fcdc4 1694
WiredHome 63:ed787f5fcdc4 1695 if(curLine8[inLineCount]==trns.col[0] ||
WiredHome 63:ed787f5fcdc4 1696 curLine8[inLineCount]==trns.col[1] ||
WiredHome 63:ed787f5fcdc4 1697 curLine8[inLineCount]==trns.col[2])
WiredHome 63:ed787f5fcdc4 1698 {
WiredHome 63:ed787f5fcdc4 1699 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1700 }
WiredHome 63:ed787f5fcdc4 1701 else
WiredHome 63:ed787f5fcdc4 1702 {
WiredHome 63:ed787f5fcdc4 1703 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1704 }
WiredHome 63:ed787f5fcdc4 1705
WiredHome 63:ed787f5fcdc4 1706 x++;
WiredHome 63:ed787f5fcdc4 1707 inLineCount++;
WiredHome 63:ed787f5fcdc4 1708 break;
WiredHome 63:ed787f5fcdc4 1709 }
WiredHome 63:ed787f5fcdc4 1710 break;
WiredHome 63:ed787f5fcdc4 1711
WiredHome 63:ed787f5fcdc4 1712
WiredHome 63:ed787f5fcdc4 1713 // True color
WiredHome 63:ed787f5fcdc4 1714 case 2:
WiredHome 63:ed787f5fcdc4 1715 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1716 {
WiredHome 63:ed787f5fcdc4 1717 case 8:
WiredHome 63:ed787f5fcdc4 1718 curLine8[inLineCount+inPixelCount]=dat;
WiredHome 63:ed787f5fcdc4 1719 inPixelCount++;
WiredHome 63:ed787f5fcdc4 1720 if(inPixelCount==3)
WiredHome 63:ed787f5fcdc4 1721 {
WiredHome 63:ed787f5fcdc4 1722 Filter8(curLine8,prvLine8,x,y,3,filter);
WiredHome 63:ed787f5fcdc4 1723
WiredHome 63:ed787f5fcdc4 1724 index=interlaceX*4+interlaceY*wid*4;
WiredHome 63:ed787f5fcdc4 1725 rgba[index ]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1726 rgba[index+1]=curLine8[inLineCount+1];
WiredHome 63:ed787f5fcdc4 1727 rgba[index+2]=curLine8[inLineCount+2];
WiredHome 63:ed787f5fcdc4 1728
WiredHome 63:ed787f5fcdc4 1729 if(curLine8[inLineCount ]==trns.col[0] &&
WiredHome 63:ed787f5fcdc4 1730 curLine8[inLineCount+1]==trns.col[1] &&
WiredHome 63:ed787f5fcdc4 1731 curLine8[inLineCount+2]==trns.col[2])
WiredHome 63:ed787f5fcdc4 1732 {
WiredHome 63:ed787f5fcdc4 1733 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1734 }
WiredHome 63:ed787f5fcdc4 1735 else
WiredHome 63:ed787f5fcdc4 1736 {
WiredHome 63:ed787f5fcdc4 1737 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1738 }
WiredHome 63:ed787f5fcdc4 1739
WiredHome 63:ed787f5fcdc4 1740 x++;
WiredHome 63:ed787f5fcdc4 1741 inLineCount+=3;
WiredHome 63:ed787f5fcdc4 1742 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1743 }
WiredHome 63:ed787f5fcdc4 1744 break;
WiredHome 63:ed787f5fcdc4 1745
WiredHome 63:ed787f5fcdc4 1746 case 16:
WiredHome 63:ed787f5fcdc4 1747 curLine8[inLineCount+inPixelCount]=dat;
WiredHome 63:ed787f5fcdc4 1748 inPixelCount++;
WiredHome 63:ed787f5fcdc4 1749 if(inPixelCount==6)
WiredHome 63:ed787f5fcdc4 1750 {
WiredHome 63:ed787f5fcdc4 1751 Filter8(curLine8,prvLine8,x,y,6,filter);
WiredHome 63:ed787f5fcdc4 1752 index=interlaceX*4+interlaceY*wid*4;
WiredHome 63:ed787f5fcdc4 1753 rgba[index ]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1754 rgba[index+1]=curLine8[inLineCount+2];
WiredHome 63:ed787f5fcdc4 1755 rgba[index+2]=curLine8[inLineCount+4];
WiredHome 63:ed787f5fcdc4 1756
WiredHome 63:ed787f5fcdc4 1757 r=curLine8[inLineCount ]*256+curLine8[inLineCount+1];
WiredHome 63:ed787f5fcdc4 1758 g=curLine8[inLineCount+2]*256+curLine8[inLineCount+3];
WiredHome 63:ed787f5fcdc4 1759 b=curLine8[inLineCount+4]*256+curLine8[inLineCount+5];
WiredHome 63:ed787f5fcdc4 1760
WiredHome 63:ed787f5fcdc4 1761 if(r==trns.col[0] && g==trns.col[1] && b==trns.col[2])
WiredHome 63:ed787f5fcdc4 1762 // Fixed based on a bug report from a viewer. Thanks for the good catch!
WiredHome 63:ed787f5fcdc4 1763 // Report received 09/10/2010
WiredHome 63:ed787f5fcdc4 1764 // Fixed 09/18/2010
WiredHome 63:ed787f5fcdc4 1765 {
WiredHome 63:ed787f5fcdc4 1766 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1767 }
WiredHome 63:ed787f5fcdc4 1768 else
WiredHome 63:ed787f5fcdc4 1769 {
WiredHome 63:ed787f5fcdc4 1770 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1771 }
WiredHome 63:ed787f5fcdc4 1772
WiredHome 63:ed787f5fcdc4 1773 x++;
WiredHome 63:ed787f5fcdc4 1774 inLineCount+=6;
WiredHome 63:ed787f5fcdc4 1775 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1776 }
WiredHome 63:ed787f5fcdc4 1777 break;
WiredHome 63:ed787f5fcdc4 1778 }
WiredHome 63:ed787f5fcdc4 1779 break;
WiredHome 63:ed787f5fcdc4 1780
WiredHome 63:ed787f5fcdc4 1781
WiredHome 63:ed787f5fcdc4 1782
WiredHome 63:ed787f5fcdc4 1783 // Indexed color
WiredHome 63:ed787f5fcdc4 1784 case 3:
WiredHome 63:ed787f5fcdc4 1785 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1786 {
WiredHome 63:ed787f5fcdc4 1787 case 8:
WiredHome 63:ed787f5fcdc4 1788 curLine8[inLineCount]=dat;
WiredHome 63:ed787f5fcdc4 1789 Filter8(curLine8,prvLine8,x,y,1,filter);
WiredHome 63:ed787f5fcdc4 1790
WiredHome 63:ed787f5fcdc4 1791 index=interlaceX*4+interlaceY*wid*4;
WiredHome 63:ed787f5fcdc4 1792 colIdx=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1793 if(colIdx<plt.nEntry)
WiredHome 63:ed787f5fcdc4 1794 {
WiredHome 63:ed787f5fcdc4 1795 rgba[index ]=plt.entry[colIdx*3 ];
WiredHome 63:ed787f5fcdc4 1796 rgba[index+1]=plt.entry[colIdx*3+1];
WiredHome 63:ed787f5fcdc4 1797 rgba[index+2]=plt.entry[colIdx*3+2];
WiredHome 63:ed787f5fcdc4 1798 if(colIdx==trns.col[0] || colIdx==trns.col[1] || colIdx==trns.col[2])
WiredHome 63:ed787f5fcdc4 1799 {
WiredHome 63:ed787f5fcdc4 1800 rgba[index+3]=0;
WiredHome 63:ed787f5fcdc4 1801 }
WiredHome 63:ed787f5fcdc4 1802 else
WiredHome 63:ed787f5fcdc4 1803 {
WiredHome 63:ed787f5fcdc4 1804 rgba[index+3]=255;
WiredHome 63:ed787f5fcdc4 1805 }
WiredHome 63:ed787f5fcdc4 1806 }
WiredHome 63:ed787f5fcdc4 1807
WiredHome 63:ed787f5fcdc4 1808 x++;
WiredHome 63:ed787f5fcdc4 1809 inLineCount++;
WiredHome 63:ed787f5fcdc4 1810 break;
WiredHome 63:ed787f5fcdc4 1811 }
WiredHome 63:ed787f5fcdc4 1812 break;
WiredHome 63:ed787f5fcdc4 1813
WiredHome 63:ed787f5fcdc4 1814
WiredHome 63:ed787f5fcdc4 1815
WiredHome 63:ed787f5fcdc4 1816 // Greyscale with alpha
WiredHome 63:ed787f5fcdc4 1817 case 4:
WiredHome 63:ed787f5fcdc4 1818 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1819 {
WiredHome 63:ed787f5fcdc4 1820 case 8:
WiredHome 63:ed787f5fcdc4 1821 curLine8[inLineCount+inPixelCount]=dat;
WiredHome 63:ed787f5fcdc4 1822 inPixelCount++;
WiredHome 63:ed787f5fcdc4 1823 if(inPixelCount==2)
WiredHome 63:ed787f5fcdc4 1824 {
WiredHome 63:ed787f5fcdc4 1825 Filter8(curLine8,prvLine8,x,y,2,filter);
WiredHome 63:ed787f5fcdc4 1826
WiredHome 63:ed787f5fcdc4 1827 index=interlaceX*4+interlaceY*wid*4;
WiredHome 63:ed787f5fcdc4 1828 rgba[index ]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1829 rgba[index+1]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1830 rgba[index+2]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1831 rgba[index+3]=curLine8[inLineCount+1];
WiredHome 63:ed787f5fcdc4 1832
WiredHome 63:ed787f5fcdc4 1833 x++;
WiredHome 63:ed787f5fcdc4 1834 inLineCount+=2;
WiredHome 63:ed787f5fcdc4 1835 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1836 }
WiredHome 63:ed787f5fcdc4 1837 break;
WiredHome 63:ed787f5fcdc4 1838 }
WiredHome 63:ed787f5fcdc4 1839 break;
WiredHome 63:ed787f5fcdc4 1840
WiredHome 63:ed787f5fcdc4 1841
WiredHome 63:ed787f5fcdc4 1842
WiredHome 63:ed787f5fcdc4 1843 // Truecolor with alpha
WiredHome 63:ed787f5fcdc4 1844 case 6:
WiredHome 63:ed787f5fcdc4 1845 switch(hdr.bitDepth)
WiredHome 63:ed787f5fcdc4 1846 {
WiredHome 63:ed787f5fcdc4 1847 case 8:
WiredHome 63:ed787f5fcdc4 1848 curLine8[inLineCount+inPixelCount]=dat;
WiredHome 63:ed787f5fcdc4 1849 inPixelCount++;
WiredHome 63:ed787f5fcdc4 1850 if(inPixelCount==4)
WiredHome 63:ed787f5fcdc4 1851 {
WiredHome 63:ed787f5fcdc4 1852 Filter8(curLine8,prvLine8,x,y,4,filter);
WiredHome 63:ed787f5fcdc4 1853
WiredHome 63:ed787f5fcdc4 1854 index=interlaceX*4+interlaceY*wid*4;
WiredHome 63:ed787f5fcdc4 1855 rgba[index ]=curLine8[inLineCount ];
WiredHome 63:ed787f5fcdc4 1856 rgba[index+1]=curLine8[inLineCount+1];
WiredHome 63:ed787f5fcdc4 1857 rgba[index+2]=curLine8[inLineCount+2];
WiredHome 63:ed787f5fcdc4 1858 rgba[index+3]=curLine8[inLineCount+3];
WiredHome 63:ed787f5fcdc4 1859
WiredHome 63:ed787f5fcdc4 1860 x++;
WiredHome 63:ed787f5fcdc4 1861 inLineCount+=4;
WiredHome 63:ed787f5fcdc4 1862 inPixelCount=0;
WiredHome 63:ed787f5fcdc4 1863 }
WiredHome 63:ed787f5fcdc4 1864 break;
WiredHome 63:ed787f5fcdc4 1865 }
WiredHome 63:ed787f5fcdc4 1866 break;
WiredHome 63:ed787f5fcdc4 1867 } // switch(hdr.colorType)
WiredHome 63:ed787f5fcdc4 1868
WiredHome 63:ed787f5fcdc4 1869 if(x>=interlaceWid)
WiredHome 63:ed787f5fcdc4 1870 {
WiredHome 63:ed787f5fcdc4 1871 y++;
WiredHome 63:ed787f5fcdc4 1872 x=-1;
WiredHome 63:ed787f5fcdc4 1873 ShiftTwoLineBuf();
WiredHome 63:ed787f5fcdc4 1874 if(y>=interlaceHei)
WiredHome 63:ed787f5fcdc4 1875 {
WiredHome 63:ed787f5fcdc4 1876 y=0;
WiredHome 63:ed787f5fcdc4 1877 interlacePass++;
WiredHome 63:ed787f5fcdc4 1878
WiredHome 63:ed787f5fcdc4 1879 INFO("Interlace Pass %d",interlacePass);
WiredHome 63:ed787f5fcdc4 1880 }
WiredHome 63:ed787f5fcdc4 1881 }
WiredHome 63:ed787f5fcdc4 1882
WiredHome 63:ed787f5fcdc4 1883 return YSOK;
WiredHome 63:ed787f5fcdc4 1884 default:
WiredHome 63:ed787f5fcdc4 1885 ERR("Unsupported interlace method.");
WiredHome 63:ed787f5fcdc4 1886 return YSERR;
WiredHome 63:ed787f5fcdc4 1887 }
WiredHome 63:ed787f5fcdc4 1888 }
WiredHome 63:ed787f5fcdc4 1889 // return YSERR; // unreachable
WiredHome 63:ed787f5fcdc4 1890 }
WiredHome 63:ed787f5fcdc4 1891
WiredHome 63:ed787f5fcdc4 1892 int YsRawPngDecoder::EndOutput(void)
WiredHome 63:ed787f5fcdc4 1893 {
WiredHome 63:ed787f5fcdc4 1894 INFO("Final Position (%d,%d)",x,y);
WiredHome 63:ed787f5fcdc4 1895 return YSOK;
WiredHome 63:ed787f5fcdc4 1896 }
WiredHome 63:ed787f5fcdc4 1897
WiredHome 63:ed787f5fcdc4 1898 void YsRawPngDecoder::Flip(void) // For drawing in OpenGL
WiredHome 63:ed787f5fcdc4 1899 {
WiredHome 63:ed787f5fcdc4 1900 int x,y,bytePerLine;
WiredHome 63:ed787f5fcdc4 1901 unsigned int swp;
WiredHome 63:ed787f5fcdc4 1902 bytePerLine=wid*4;
WiredHome 63:ed787f5fcdc4 1903 for(y=0; y<hei/2; y++)
WiredHome 63:ed787f5fcdc4 1904 {
WiredHome 63:ed787f5fcdc4 1905 for(x=0; x<bytePerLine; x++)
WiredHome 63:ed787f5fcdc4 1906 {
WiredHome 63:ed787f5fcdc4 1907 swp=rgba[y*bytePerLine+x];
WiredHome 63:ed787f5fcdc4 1908 rgba[y*bytePerLine+x]=rgba[(hei-1-y)*bytePerLine+x];
WiredHome 63:ed787f5fcdc4 1909 rgba[(hei-1-y)*bytePerLine+x]=swp;
WiredHome 63:ed787f5fcdc4 1910 }
WiredHome 63:ed787f5fcdc4 1911 }
WiredHome 63:ed787f5fcdc4 1912 }