#include #include 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) { free(jpg->DataImg); 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 *)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 (klHuffTable[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=1; // TRUE } if (el==0xC4) { ClbJpegFillHuffTable(jpg); } if (el==0xDA) { jpg->lSos.CompCount=fgetc(jpg->infp); for (tp=0;tplSos.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*)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;iXlSof.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;iYlSof.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;iXlSof.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;iYRestartInterval;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