--- /dev/null
+#include <iddcmjpeg.h>
+
+
+static ClbJpeg* ClbJpegAlloc(void);
+static void ClbJpegInit (ClbJpeg *);
+static int ClbJpegDecodeDiff(ClbJpeg *);
+static BOOL ClbJpegDecodeData(ClbJpeg *);
+static int ClbJpegReadBit(ClbJpeg *);
+static BOOL ClbJpegReadHeader(ClbJpeg *);
+static BOOL ClbJpegStart(ClbJpeg *,FILE *);
+static BOOL ClbJpegFillHuffTable(ClbJpeg *);
+
+
+
+
+void _IdDcmJpegFree(ClbJpeg *jpg)
+{
+ g_free(jpg->DataImg);
+ g_free(jpg);
+}
+
+
+ClbJpeg * _IdDcmJpegRead (FILE * fp){
+ClbJpeg * jpg=NULL;
+ jpg=ClbJpegAlloc();
+ if(!jpg)
+ return(NULL);
+ ClbJpegInit (jpg);
+ if(!ClbJpegStart(jpg, fp))
+ return (NULL);
+ return (jpg);
+}
+
+
+
+static void ClbJpegInit (ClbJpeg *jpg) {
+int n;
+ for (n=0;n<256;n++)
+ {
+ jpg->lHuffTable[n].HufCode=0;
+ jpg->lHuffTable[n].HufSz=0;
+ jpg->lHuffTable[n].HufVal=0;
+ }
+ jpg->ValCurByte=0;
+ jpg->PosCurBit=10;
+ jpg->MarkerFound=0;
+ jpg->RestartInterval=0;
+}
+
+static ClbJpeg *ClbJpegAlloc(void) {
+ClbJpeg * jpg;
+ jpg = (ClbJpeg *)g_malloc(sizeof(ClbJpeg));
+ ClbJpegInit(jpg);
+return jpg;
+}
+
+
+
+static BOOL ClbJpegFillHuffTable(ClbJpeg *jpg)
+{
+ unsigned char c;
+ //int testindex=0;
+ int n=0;
+ int NiDHT=0;
+ int indexY=0;
+ int k, Code, Si, i;
+
+ for (c=0;c<255;c++)
+ jpg->RawDHTstart[c]=0;
+
+ c=fgetc(jpg->infp);
+
+
+ jpg->MaxHuffSz=0;
+ jpg->MaxHuffVal=0;
+
+ for (n=1;n<17;n++)
+ {
+ jpg->RawDHT[n]=fgetc(jpg->infp);
+ NiDHT+=jpg->RawDHT[n];
+ if (jpg->RawDHT[n]!=0)
+ jpg->MaxHuffSz=n;
+ }
+
+ for(n=1;n<16;n++)
+ {
+ if(jpg->RawDHT[n]>0)
+ {
+ jpg->RawDHTstart[n]=indexY+1;
+ for (i=1;i<(jpg->RawDHT[n]+1);i++)
+ {
+ indexY+=1;
+ c=fgetc(jpg->infp);
+ jpg->lHuffTable[indexY].HufVal=c;
+ jpg->MaxHuffVal=c;
+ jpg->lHuffTable[indexY].HufSz=n;
+ }
+ }
+ }
+ k=1;
+ Code=0;
+
+ Si=jpg->lHuffTable[k].HufSz;
+
+ while(1)
+ {
+ if (k>=NiDHT) break;
+ while( Si==jpg->lHuffTable[k].HufSz)
+ {
+ jpg->lHuffTable[k].HufCode=Code;
+ Code+=1;
+ k+=1;
+ }
+ if (k<NiDHT)
+ {
+ while (jpg->lHuffTable[k].HufSz>Si)
+ {
+ Code=Code<<1;
+ Si+=1;
+ }
+ }
+ }
+
+ return 1;
+}
+
+
+
+static BOOL ClbJpegStart(ClbJpeg *jpg, FILE *inputfp)
+{
+ jpg->infp=inputfp;
+ if (!ClbJpegReadHeader(jpg)) return 0;
+ //printf("sortie ClbJpegReadHeader\n");
+ if (!ClbJpegDecodeData(jpg)) return 0;
+ //printf("sortie ClbJpegDecodeData\n");
+ return 1;
+}
+
+static BOOL ClbJpegReadHeader(ClbJpeg *jpg)
+{
+ unsigned char gr;
+ unsigned char el;
+ unsigned char l2;
+ unsigned char l1;
+ unsigned int sztag;
+ long ouca=0;
+ BOOL HeaderEnd=0;
+ BOOL isLossLess=0;
+
+ int tp;
+
+ gr=fgetc(jpg->infp); //FF
+ el=fgetc(jpg->infp); //D8
+
+ while(!HeaderEnd)
+ {
+ gr=fgetc(jpg->infp);
+ if(gr!=0xFF) return 0;
+ el=fgetc(jpg->infp);
+
+ if ( (el==0xFF) || (el==0x01) || (el==0xD8) ||(el==0xD9) ||( (el>=0xD0) && (el<=0xD7) ))
+ ;
+ else
+ {
+ l1=fgetc(jpg->infp);
+ l2=fgetc(jpg->infp);
+ sztag=(l1*256)+l2-2; //tag lengh
+ ouca=ftell(jpg->infp);
+
+ if (el==0xC3)
+ {
+ jpg->lSof.precision=fgetc(jpg->infp);
+
+ l1=fgetc(jpg->infp);
+ l2=fgetc(jpg->infp);
+ jpg->lSof.Himg=(l1*256)+l2;
+
+ l1=fgetc(jpg->infp);
+ l2=fgetc(jpg->infp);
+ jpg->lSof.Wimg=(l1*256)+l2;
+
+ jpg->lSof.NbComponent=fgetc(jpg->infp);
+
+ jpg->lSof.SofTabPos=ftell(jpg->infp);
+
+ isLossLess=TRUE;
+ }
+
+ if (el==0xC4)
+ {
+ ClbJpegFillHuffTable(jpg);
+ }
+ if (el==0xDA)
+ {
+ jpg->lSos.CompCount=fgetc(jpg->infp);
+ for (tp=0;tp<jpg->lSos.CompCount;tp++)
+ {
+ jpg->lSos.CompId=fgetc(jpg->infp);
+ jpg->lSos.CompDc=fgetc(jpg->infp);
+ }
+ jpg->lSos.SpectralSelStart=fgetc(jpg->infp);
+ jpg->lSos.SpectralSelEnd=fgetc(jpg->infp);
+ jpg->lSos.SuccessiveAp=fgetc(jpg->infp);
+ jpg->lSos.Sospttrans=(jpg->lSos.SuccessiveAp & 16);
+ HeaderEnd=1;
+ }
+ if (el==0xDD)
+ {
+ l1=fgetc(jpg->infp);
+ l2=fgetc(jpg->infp);
+ jpg->RestartInterval=(l1*256)+l2;
+ }
+
+ fseek(jpg->infp,(ouca+sztag),0);
+ }
+ }
+
+ if (!isLossLess) return 0;
+ return 1;
+
+}
+
+static int ClbJpegReadBit(ClbJpeg *jpg)
+{
+ int r=0;
+ unsigned char c;
+ if(jpg->PosCurBit>8) // need lire octet suivant
+ {
+ jpg->ValCurByte=fgetc(jpg->infp);
+ if (jpg->ValCurByte==0xFF)
+ {
+ c=fgetc(jpg->infp);// est 00 ou restart marker: a skiper
+ if (c!=0)
+ {
+ jpg->ValCurByte=fgetc(jpg->infp);
+ jpg->PosCurBit=1;
+ jpg->MarkerFound=1;
+ return 0;
+ }
+ }
+ jpg->PosCurBit=2;
+ return (jpg->ValCurByte>>7);
+ }
+ else
+ {
+ r=(1&(jpg->ValCurByte>>(8-jpg->PosCurBit)));
+ jpg->PosCurBit+=1;
+ return r;
+ }
+}
+
+
+static BOOL ClbJpegDecodeData(ClbJpeg *jpg)
+{
+ int iX,iY;
+ int lbInc=0;
+ unsigned int mask;
+
+ int lPredicted=(1<<(jpg->lSof.precision-1-jpg->lSos.Sospttrans));
+
+ jpg->ValCurByte=jpg->lSos.SuccessiveAp;
+ jpg->PosCurBit=9;
+
+ if (jpg->lSof.precision==8)
+ mask=0xFF;
+ if (jpg->lSof.precision==12)
+ mask=0xFFF;
+ if (jpg->lSof.precision==16)
+ mask=0xFFFF;
+
+ jpg->DataImg=(int*)g_malloc(jpg->lSof.Himg*jpg->lSof.Wimg*sizeof(*jpg->DataImg));
+ memset( jpg->DataImg,0,(jpg->lSof.Himg*jpg->lSof.Wimg*sizeof(*jpg->DataImg)));
+
+ if (!jpg->RestartInterval)
+ {
+ for(iX=0;iX<jpg->lSof.Wimg;iX++) // lit première ligne
+ {
+ lbInc+=1;
+ if (lbInc>1)
+ lPredicted= jpg->DataImg[lbInc-1];
+ jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg);
+
+ if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) )
+ jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
+ if ( jpg->DataImg[lbInc]<0)
+ jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
+ }
+
+ for (iY=1;iY<jpg->lSof.Himg;iY++) //lit la suite
+ {
+ lbInc+=1;
+ if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) break;
+ lPredicted= jpg->DataImg[lbInc-jpg->lSof.Wimg]; // se base % premier é ligne d'avant
+ jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg);
+
+ if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) )
+ jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
+ if ( jpg->DataImg[lbInc]<0)
+ jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
+
+ for(iX=1;iX<jpg->lSof.Wimg;iX++)
+ {
+ lbInc+=1;
+ if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) break;
+ if (jpg->lSos.SpectralSelStart==7) // si spectral
+ lPredicted=( jpg->DataImg[lbInc-1]+ jpg->DataImg[lbInc-jpg->lSof.Wimg])>>1;
+ else
+ lPredicted= jpg->DataImg[lbInc-1]; // se base%pixel juste avant
+ jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg);
+
+ if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) )
+ jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
+ if ( jpg->DataImg[lbInc]<0)
+ jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
+
+ }
+ }
+ }
+ else // il y a un define interval
+ {
+ while(1)
+ {
+ jpg->MarkerFound=0;
+ lPredicted=(1<<(jpg->lSof.precision - 1 - jpg->lSos.Sospttrans));
+ for (iY=0;iY<jpg->RestartInterval;iY++)
+ {
+ jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg);
+
+ if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) )
+ jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
+ if ( jpg->DataImg[lbInc]<0)
+ jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask;
+
+ lbInc+=1;
+ if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) return 1;
+
+ if (jpg->lSos.SpectralSelStart==7) // si spectral
+ lPredicted=( jpg->DataImg[lbInc-1]+ jpg->DataImg[lbInc-jpg->lSof.Wimg])>>1;
+ else
+ lPredicted= jpg->DataImg[lbInc-1];
+ }
+ while (!jpg->MarkerFound)
+ {
+ ClbJpegReadBit(jpg); // skip bits restant avant restart marker
+ }
+ }
+ }
+ return 1;
+}
+
+static int ClbJpegDecodeDiff(ClbJpeg *jpg)
+{
+ int lInput;
+ int lInputBits;
+ int lHufVal;
+ int lDiff;
+ int lI;
+ int resultat;
+ lHufVal = 666;
+ lInput = 0;
+ lInputBits = 0;
+
+
+ while (1)
+ {
+ lInputBits+=1;
+ lInput=(lInput<<1)+ClbJpegReadBit(jpg);
+ if (jpg->RawDHT[lInputBits]!=0)
+ {
+ for(lI=jpg->RawDHTstart[lInputBits];lI<(jpg->RawDHTstart[lInputBits]+jpg->RawDHT[lInputBits]);lI++)
+ {
+ if (lInput==jpg->lHuffTable[lI].HufCode)
+ lHufVal=jpg->lHuffTable[lI].HufVal;
+ }
+ }
+ if (lInputBits>=jpg->MaxHuffSz)
+ lHufVal=jpg->MaxHuffVal;
+ if (lHufVal<255) break;
+ }
+ if (lHufVal==0) resultat= 0;
+
+ if ( (lHufVal>0) && (lHufVal<16))
+ {
+ lDiff=0;
+ if( ClbJpegReadBit(jpg)==1)
+ {
+ for (lI=1;lI<lHufVal;lI++)
+ {
+ lDiff=(lDiff<<1)+ClbJpegReadBit(jpg);
+ }
+
+ resultat= (lDiff+(1<<(lHufVal-1)));
+ }
+ else
+ {
+ for (lI=1;lI<lHufVal;lI++)
+ lDiff=(lDiff<<1)+1-ClbJpegReadBit(jpg);
+ resultat= -(lDiff+(1<<(lHufVal-1)));
+ }
+ }
+
+ return resultat;
+
+}