From 9bc083b6f1fec37a7a437e07bc9c6f08d40746e4 Mon Sep 17 00:00:00 2001 From: jpr Date: Wed, 12 Mar 2003 13:27:56 +0000 Subject: [PATCH] Ajout temporaire de la fonction LibIDO de lecture Jpeg Lossless --- src/gdcmJpeg.cxx | 404 +++++++++++++++++++++++++++++++++++++++++++++++ src/iddcmjpeg.h | 60 +++++++ 2 files changed, 464 insertions(+) create mode 100644 src/gdcmJpeg.cxx create mode 100644 src/iddcmjpeg.h diff --git a/src/gdcmJpeg.cxx b/src/gdcmJpeg.cxx new file mode 100644 index 00000000..f0278c62 --- /dev/null +++ b/src/gdcmJpeg.cxx @@ -0,0 +1,404 @@ +#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) +{ + 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 (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=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*)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;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 +#include + +#define BOOL int + +typedef struct { + int HufSz; + int HufCode; + int HufVal; +} HuffTable; + + +typedef struct { + unsigned char precision; + int Himg; + int Wimg; + unsigned char NbComponent; + long SofTabPos; +} Sof; + + +typedef struct { + unsigned char CompCount; + unsigned char CompId; + unsigned char CompDc; + unsigned char SpectralSelStart; + unsigned char SpectralSelEnd; + unsigned char SuccessiveAp; + unsigned char Sospttrans; + long SofTabPos; +} Sos; + + +typedef struct { + unsigned long RestartInterval; + BOOL MarkerFound; + int MaxHuffVal; + int MaxHuffSz; + int* DataImg; + unsigned char RawDHT[256]; + unsigned char ValCurByte; + unsigned char PosCurBit; + FILE* infp; + unsigned char RawDHTstart[256]; + Sof lSof; + Sos lSos; + HuffTable lHuffTable[256]; +} ClbJpeg; + + +ClbJpeg*_IdDcmJpegRead (FILE *); +void _IdDcmJpegFree (ClbJpeg *); + + +// + + + + + -- 2.48.1