4 static ClbJpeg* ClbJpegAlloc(void);
5 static void ClbJpegInit (ClbJpeg *);
6 static int ClbJpegDecodeDiff(ClbJpeg *);
7 static BOOL ClbJpegDecodeData(ClbJpeg *);
8 static int ClbJpegReadBit(ClbJpeg *);
9 static BOOL ClbJpegReadHeader(ClbJpeg *);
10 static BOOL ClbJpegStart(ClbJpeg *,FILE *);
11 static BOOL ClbJpegFillHuffTable(ClbJpeg *);
16 void _IdDcmJpegFree(ClbJpeg *jpg)
23 ClbJpeg * _IdDcmJpegRead (FILE * fp){
29 if(!ClbJpegStart(jpg, fp))
36 static void ClbJpegInit (ClbJpeg *jpg) {
40 jpg->lHuffTable[n].HufCode=0;
41 jpg->lHuffTable[n].HufSz=0;
42 jpg->lHuffTable[n].HufVal=0;
47 jpg->RestartInterval=0;
50 static ClbJpeg *ClbJpegAlloc(void) {
52 jpg = (ClbJpeg *)g_malloc(sizeof(ClbJpeg));
59 static BOOL ClbJpegFillHuffTable(ClbJpeg *jpg)
69 jpg->RawDHTstart[c]=0;
79 jpg->RawDHT[n]=fgetc(jpg->infp);
80 NiDHT+=jpg->RawDHT[n];
81 if (jpg->RawDHT[n]!=0)
89 jpg->RawDHTstart[n]=indexY+1;
90 for (i=1;i<(jpg->RawDHT[n]+1);i++)
94 jpg->lHuffTable[indexY].HufVal=c;
96 jpg->lHuffTable[indexY].HufSz=n;
103 Si=jpg->lHuffTable[k].HufSz;
108 while( Si==jpg->lHuffTable[k].HufSz)
110 jpg->lHuffTable[k].HufCode=Code;
116 while (jpg->lHuffTable[k].HufSz>Si)
129 static BOOL ClbJpegStart(ClbJpeg *jpg, FILE *inputfp)
132 if (!ClbJpegReadHeader(jpg)) return 0;
133 //printf("sortie ClbJpegReadHeader\n");
134 if (!ClbJpegDecodeData(jpg)) return 0;
135 //printf("sortie ClbJpegDecodeData\n");
139 static BOOL ClbJpegReadHeader(ClbJpeg *jpg)
152 gr=fgetc(jpg->infp); //FF
153 el=fgetc(jpg->infp); //D8
158 if(gr!=0xFF) return 0;
161 if ( (el==0xFF) || (el==0x01) || (el==0xD8) ||(el==0xD9) ||( (el>=0xD0) && (el<=0xD7) ))
167 sztag=(l1*256)+l2-2; //tag lengh
168 ouca=ftell(jpg->infp);
172 jpg->lSof.precision=fgetc(jpg->infp);
176 jpg->lSof.Himg=(l1*256)+l2;
180 jpg->lSof.Wimg=(l1*256)+l2;
182 jpg->lSof.NbComponent=fgetc(jpg->infp);
184 jpg->lSof.SofTabPos=ftell(jpg->infp);
191 ClbJpegFillHuffTable(jpg);
195 jpg->lSos.CompCount=fgetc(jpg->infp);
196 for (tp=0;tp<jpg->lSos.CompCount;tp++)
198 jpg->lSos.CompId=fgetc(jpg->infp);
199 jpg->lSos.CompDc=fgetc(jpg->infp);
201 jpg->lSos.SpectralSelStart=fgetc(jpg->infp);
202 jpg->lSos.SpectralSelEnd=fgetc(jpg->infp);
203 jpg->lSos.SuccessiveAp=fgetc(jpg->infp);
204 jpg->lSos.Sospttrans=(jpg->lSos.SuccessiveAp & 16);
211 jpg->RestartInterval=(l1*256)+l2;
214 fseek(jpg->infp,(ouca+sztag),0);
218 if (!isLossLess) return 0;
223 static int ClbJpegReadBit(ClbJpeg *jpg)
227 if(jpg->PosCurBit>8) // need lire octet suivant
229 jpg->ValCurByte=fgetc(jpg->infp);
230 if (jpg->ValCurByte==0xFF)
232 c=fgetc(jpg->infp);// est 00 ou restart marker: a skiper
235 jpg->ValCurByte=fgetc(jpg->infp);
242 return (jpg->ValCurByte>>7);
246 r=(1&(jpg->ValCurByte>>(8-jpg->PosCurBit)));
253 static BOOL ClbJpegDecodeData(ClbJpeg *jpg)
259 int lPredicted=(1<<(jpg->lSof.precision-1-jpg->lSos.Sospttrans));
261 jpg->ValCurByte=jpg->lSos.SuccessiveAp;
264 if (jpg->lSof.precision==8)
266 if (jpg->lSof.precision==12)
268 if (jpg->lSof.precision==16)
271 jpg->DataImg=(int*)g_malloc(jpg->lSof.Himg*jpg->lSof.Wimg*sizeof(*jpg->DataImg));
272 memset( jpg->DataImg,0,(jpg->lSof.Himg*jpg->lSof.Wimg*sizeof(*jpg->DataImg)));
274 if (!jpg->RestartInterval)
276 for(iX=0;iX<jpg->lSof.Wimg;iX++) // lit première ligne
280 lPredicted= jpg->DataImg[lbInc-1];
281 jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg);
283 if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) )
284 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
285 if ( jpg->DataImg[lbInc]<0)
286 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
289 for (iY=1;iY<jpg->lSof.Himg;iY++) //lit la suite
292 if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) break;
293 lPredicted= jpg->DataImg[lbInc-jpg->lSof.Wimg]; // se base % premier é ligne d'avant
294 jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg);
296 if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) )
297 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
298 if ( jpg->DataImg[lbInc]<0)
299 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
301 for(iX=1;iX<jpg->lSof.Wimg;iX++)
304 if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) break;
305 if (jpg->lSos.SpectralSelStart==7) // si spectral
306 lPredicted=( jpg->DataImg[lbInc-1]+ jpg->DataImg[lbInc-jpg->lSof.Wimg])>>1;
308 lPredicted= jpg->DataImg[lbInc-1]; // se base%pixel juste avant
309 jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg);
311 if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) )
312 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
313 if ( jpg->DataImg[lbInc]<0)
314 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
319 else // il y a un define interval
324 lPredicted=(1<<(jpg->lSof.precision - 1 - jpg->lSos.Sospttrans));
325 for (iY=0;iY<jpg->RestartInterval;iY++)
327 jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg);
329 if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) )
330 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
331 if ( jpg->DataImg[lbInc]<0)
332 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
335 if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) return 1;
337 if (jpg->lSos.SpectralSelStart==7) // si spectral
338 lPredicted=( jpg->DataImg[lbInc-1]+ jpg->DataImg[lbInc-jpg->lSof.Wimg])>>1;
340 lPredicted= jpg->DataImg[lbInc-1];
342 while (!jpg->MarkerFound)
344 ClbJpegReadBit(jpg); // skip bits restant avant restart marker
351 static int ClbJpegDecodeDiff(ClbJpeg *jpg)
367 lInput=(lInput<<1)+ClbJpegReadBit(jpg);
368 if (jpg->RawDHT[lInputBits]!=0)
370 for(lI=jpg->RawDHTstart[lInputBits];lI<(jpg->RawDHTstart[lInputBits]+jpg->RawDHT[lInputBits]);lI++)
372 if (lInput==jpg->lHuffTable[lI].HufCode)
373 lHufVal=jpg->lHuffTable[lI].HufVal;
376 if (lInputBits>=jpg->MaxHuffSz)
377 lHufVal=jpg->MaxHuffVal;
378 if (lHufVal<255) break;
380 if (lHufVal==0) resultat= 0;
382 if ( (lHufVal>0) && (lHufVal<16))
385 if( ClbJpegReadBit(jpg)==1)
387 for (lI=1;lI<lHufVal;lI++)
389 lDiff=(lDiff<<1)+ClbJpegReadBit(jpg);
392 resultat= (lDiff+(1<<(lHufVal-1)));
396 for (lI=1;lI<lHufVal;lI++)
397 lDiff=(lDiff<<1)+1-ClbJpegReadBit(jpg);
398 resultat= -(lDiff+(1<<(lHufVal-1)));