Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals

dcmjpeg.c

Go to the documentation of this file.
00001 /************************************************************************* 00002 * $Id: dcmjpeg.c,v 1.1 2005/09/09 08:22:23 bellet Exp $ 00003 ************************************************************************** 00004 This software is governed by the CeCILL license under French law and 00005 abiding by the rules of distribution of free software. You can use, 00006 modify and/ or redistribute the software under the terms of the CeCILL 00007 license as circulated by CEA, CNRS and INRIA at the following URL 00008 "http://www.cecill.info". 00009 00010 As a counterpart to the access to the source code and rights to copy, 00011 modify and redistribute granted by the license, users are provided only 00012 with a limited warranty and the software's author, the holder of the 00013 economic rights, and the successive licensors have only limited 00014 liability. 00015 00016 In this respect, the user's attention is drawn to the risks associated 00017 with loading, using, modifying and/or developing or reproducing the 00018 software by the user in light of its specific status of free software, 00019 that may mean that it is complicated to manipulate, and that also 00020 therefore means that it is reserved for developers and experienced 00021 professionals having in-depth computer knowledge. Users are therefore 00022 encouraged to load and test the software's suitability as regards their 00023 requirements in conditions enabling the security of their systems and/or 00024 data to be ensured and, more generally, to use and operate it in the 00025 same conditions as regards security. 00026 00027 The fact that you are presently reading this means that you have had 00028 knowledge of the CeCILL license and that you accept its terms. 00029 00030 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de 00031 l'Image). All rights reserved. See License.txt for details. 00032 00033 Version 1.0 05/09/2005 00034 *************************************************************************/ 00035 00036 #include <stdlib.h> 00037 #include "iddcmjpeg.h" 00038 #include "idcommon.h" 00039 00040 00041 static ClbJpeg* ClbJpegAlloc(void); 00042 static void ClbJpegInit (ClbJpeg *); 00043 static int ClbJpegDecodeDiff(ClbJpeg *); 00044 static BOOL ClbJpegDecodeData(ClbJpeg *); 00045 static int ClbJpegReadBit(ClbJpeg *); 00046 static BOOL ClbJpegReadHeader(ClbJpeg *); 00047 static BOOL ClbJpegStart(ClbJpeg *,FILE *); 00048 static BOOL ClbJpegFillHuffTable(ClbJpeg *); 00049 00050 00051 00052 00053 void _IdDcmJpegFree(ClbJpeg *jpg) 00054 { 00055 free(jpg->DataImg); 00056 free(jpg); 00057 } 00058 00059 00060 ClbJpeg * _IdDcmJpegRead (FILE * fp){ 00061 ClbJpeg * jpg=NULL; 00062 jpg=ClbJpegAlloc(); 00063 if(!jpg) { 00064 printf("Fail to ClbJpegAlloc \n"); 00065 return(NULL); 00066 } 00067 ClbJpegInit (jpg); 00068 if(!ClbJpegStart(jpg, fp)) { 00069 printf("Fail to ClbJpegStart \n"); 00070 return (NULL); 00071 } 00072 return (jpg); 00073 } 00074 00075 00076 00077 static void ClbJpegInit (ClbJpeg *jpg) { 00078 int n; 00079 for (n=0;n<256;n++) 00080 { 00081 jpg->lHuffTable[n].HufCode=0; 00082 jpg->lHuffTable[n].HufSz=0; 00083 jpg->lHuffTable[n].HufVal=0; 00084 } 00085 jpg->ValCurByte=0; 00086 jpg->PosCurBit=10; 00087 jpg->MarkerFound=0; 00088 jpg->RestartInterval=0; 00089 } 00090 00091 static ClbJpeg *ClbJpegAlloc(void) { 00092 ClbJpeg * jpg; 00093 jpg = (ClbJpeg *)malloc(sizeof(ClbJpeg)); 00094 ClbJpegInit(jpg); 00095 return jpg; 00096 } 00097 00098 00099 00100 static BOOL ClbJpegFillHuffTable(ClbJpeg *jpg) 00101 { 00102 unsigned char c; 00103 //int testindex=0; 00104 int n=0; 00105 int NiDHT=0; 00106 int indexY=0; 00107 int k, Code, Si, i; 00108 00109 for (c=0;c<255;c++) 00110 jpg->RawDHTstart[c]=0; 00111 00112 c=fgetc(jpg->infp); 00113 00114 00115 jpg->MaxHuffSz=0; 00116 jpg->MaxHuffVal=0; 00117 00118 for (n=1;n<17;n++) 00119 { 00120 jpg->RawDHT[n]=fgetc(jpg->infp); 00121 NiDHT+=jpg->RawDHT[n]; 00122 if (jpg->RawDHT[n]!=0) 00123 jpg->MaxHuffSz=n; 00124 } 00125 00126 for(n=1;n<16;n++) 00127 { 00128 if(jpg->RawDHT[n]>0) 00129 { 00130 jpg->RawDHTstart[n]=indexY+1; 00131 for (i=1;i<(jpg->RawDHT[n]+1);i++) 00132 { 00133 indexY+=1; 00134 c=fgetc(jpg->infp); 00135 jpg->lHuffTable[indexY].HufVal=c; 00136 jpg->MaxHuffVal=c; 00137 jpg->lHuffTable[indexY].HufSz=n; 00138 } 00139 } 00140 } 00141 k=1; 00142 Code=0; 00143 00144 Si=jpg->lHuffTable[k].HufSz; 00145 00146 while(1) 00147 { 00148 if (k>=NiDHT) break; 00149 while( Si==jpg->lHuffTable[k].HufSz) 00150 { 00151 jpg->lHuffTable[k].HufCode=Code; 00152 Code+=1; 00153 k+=1; 00154 } 00155 if (k<NiDHT) 00156 { 00157 while (jpg->lHuffTable[k].HufSz>Si) 00158 { 00159 Code=Code<<1; 00160 Si+=1; 00161 } 00162 } 00163 } 00164 00165 return 1; 00166 } 00167 00168 00169 00170 static BOOL ClbJpegStart(ClbJpeg *jpg, FILE *inputfp) 00171 { 00172 jpg->infp=inputfp; 00173 if (!ClbJpegReadHeader(jpg)) { 00174 printf("Fail to ClbJpegReadHeader\n"); 00175 return 0; 00176 } 00177 //printf("sortie ClbJpegReadHeader\n"); 00178 if (!ClbJpegDecodeData(jpg)) { 00179 printf("Fail to ClbJpegDecodeData\n"); 00180 return 0; 00181 } 00182 //printf("sortie ClbJpegDecodeData\n"); 00183 return 1; 00184 } 00185 00186 static BOOL ClbJpegReadHeader(ClbJpeg *jpg) 00187 { 00188 unsigned char gr; 00189 unsigned char el; 00190 unsigned char l2; 00191 unsigned char l1; 00192 unsigned int sztag; 00193 long ouca=0; 00194 BOOL HeaderEnd=0; 00195 BOOL isLossLess=0; 00196 00197 int tp; 00198 00199 gr=fgetc(jpg->infp); //FF 00200 el=fgetc(jpg->infp); //D8 00201 00202 while(!HeaderEnd) 00203 { 00204 gr=fgetc(jpg->infp); 00205 if(gr!=0xFF) { 00206 printf("gr!=0xFF (=%02x)\n",gr); 00207 return 0; 00208 } 00209 el=fgetc(jpg->infp); 00210 00211 if ( (el==0xFF) || (el==0x01) || (el==0xD8) ||(el==0xD9) ||( (el>=0xD0) && (el<=0xD7) )) 00212 ; 00213 else 00214 { 00215 l1=fgetc(jpg->infp); 00216 l2=fgetc(jpg->infp); 00217 sztag=(l1*256)+l2-2; //tag lengh 00218 ouca=ftell(jpg->infp); 00219 00220 if (el==0xC3) 00221 { 00222 jpg->lSof.precision=fgetc(jpg->infp); 00223 00224 l1=fgetc(jpg->infp); 00225 l2=fgetc(jpg->infp); 00226 jpg->lSof.Himg=(l1*256)+l2; 00227 00228 l1=fgetc(jpg->infp); 00229 l2=fgetc(jpg->infp); 00230 jpg->lSof.Wimg=(l1*256)+l2; 00231 00232 jpg->lSof.NbComponent=fgetc(jpg->infp); 00233 00234 jpg->lSof.SofTabPos=ftell(jpg->infp); 00235 00236 isLossLess=TRUE; 00237 } 00238 00239 if (el==0xC4) 00240 { 00241 ClbJpegFillHuffTable(jpg); 00242 } 00243 if (el==0xDA) 00244 { 00245 jpg->lSos.CompCount=fgetc(jpg->infp); 00246 for (tp=0;tp<jpg->lSos.CompCount;tp++) 00247 { 00248 jpg->lSos.CompId=fgetc(jpg->infp); 00249 jpg->lSos.CompDc=fgetc(jpg->infp); 00250 } 00251 jpg->lSos.SpectralSelStart=fgetc(jpg->infp); 00252 jpg->lSos.SpectralSelEnd=fgetc(jpg->infp); 00253 jpg->lSos.SuccessiveAp=fgetc(jpg->infp); 00254 jpg->lSos.Sospttrans=(jpg->lSos.SuccessiveAp & 16); 00255 HeaderEnd=1; 00256 } 00257 if (el==0xDD) 00258 { 00259 l1=fgetc(jpg->infp); 00260 l2=fgetc(jpg->infp); 00261 jpg->RestartInterval=(l1*256)+l2; 00262 } 00263 00264 fseek(jpg->infp,(ouca+sztag),0); 00265 } 00266 } 00267 00268 if (!isLossLess) { 00269 printf("NOT isLossLess\n"); 00270 return 0; 00271 } 00272 return 1; 00273 00274 } 00275 00276 static int ClbJpegReadBit(ClbJpeg *jpg) 00277 { 00278 int r=0; 00279 unsigned char c; 00280 if(jpg->PosCurBit>8) // need lire octet suivant 00281 { 00282 jpg->ValCurByte=fgetc(jpg->infp); 00283 if (jpg->ValCurByte==0xFF) 00284 { 00285 c=fgetc(jpg->infp);// est 00 ou restart marker: a skiper 00286 if (c!=0) 00287 { 00288 jpg->ValCurByte=fgetc(jpg->infp); 00289 jpg->PosCurBit=1; 00290 jpg->MarkerFound=1; 00291 return 0; 00292 } 00293 } 00294 jpg->PosCurBit=2; 00295 return (jpg->ValCurByte>>7); 00296 } 00297 else 00298 { 00299 r=(1&(jpg->ValCurByte>>(8-jpg->PosCurBit))); 00300 jpg->PosCurBit+=1; 00301 return r; 00302 } 00303 } 00304 00305 00306 static BOOL ClbJpegDecodeData(ClbJpeg *jpg) 00307 { 00308 int iX,iY; 00309 int lbInc=0; 00310 unsigned int mask; 00311 00312 int lPredicted=(1<<(jpg->lSof.precision-1-jpg->lSos.Sospttrans)); 00313 00314 jpg->ValCurByte=jpg->lSos.SuccessiveAp; 00315 jpg->PosCurBit=9; 00316 00317 if (jpg->lSof.precision==8) 00318 mask=0xFF; 00319 if (jpg->lSof.precision==12) 00320 mask=0xFFF; 00321 if (jpg->lSof.precision==16) 00322 mask=0xFFFF; 00323 00324 jpg->DataImg=(int*)malloc(jpg->lSof.Himg*jpg->lSof.Wimg*sizeof(*jpg->DataImg)); 00325 memset( jpg->DataImg,0,(jpg->lSof.Himg*jpg->lSof.Wimg*sizeof(*jpg->DataImg))); 00326 00327 if (!jpg->RestartInterval) 00328 { 00329 for(iX=0;iX<jpg->lSof.Wimg;iX++) // lit première ligne 00330 { 00331 lbInc+=1; 00332 if (lbInc>1) 00333 lPredicted= jpg->DataImg[lbInc-1]; 00334 jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg); 00335 00336 if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) ) 00337 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask; 00338 if ( jpg->DataImg[lbInc]<0) 00339 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask; 00340 } 00341 00342 for (iY=1;iY<jpg->lSof.Himg;iY++) //lit la suite 00343 { 00344 lbInc+=1; 00345 if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) break; 00346 lPredicted= jpg->DataImg[lbInc-jpg->lSof.Wimg]; // se base % premier é ligne d'avant 00347 jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg); 00348 00349 if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) ) 00350 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask; 00351 if ( jpg->DataImg[lbInc]<0) 00352 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask; 00353 00354 for(iX=1;iX<jpg->lSof.Wimg;iX++) 00355 { 00356 lbInc+=1; 00357 if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) break; 00358 if (jpg->lSos.SpectralSelStart==7) // si spectral 00359 lPredicted=( jpg->DataImg[lbInc-1]+ jpg->DataImg[lbInc-jpg->lSof.Wimg])>>1; 00360 else 00361 lPredicted= jpg->DataImg[lbInc-1]; // se base%pixel juste avant 00362 jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg); 00363 00364 if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) ) 00365 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask; 00366 if ( jpg->DataImg[lbInc]<0) 00367 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask; 00368 00369 } 00370 } 00371 } 00372 else // il y a un define interval 00373 { 00374 while(1) 00375 { 00376 jpg->MarkerFound=0; 00377 lPredicted=(1<<(jpg->lSof.precision - 1 - jpg->lSos.Sospttrans)); 00378 for (iY=0;iY<jpg->RestartInterval;iY++) 00379 { 00380 jpg->DataImg[lbInc]=lPredicted+ClbJpegDecodeDiff(jpg); 00381 00382 if ( jpg->DataImg[lbInc] > ((1<<(jpg->lSof.precision))-1) ) 00383 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask; 00384 if ( jpg->DataImg[lbInc]<0) 00385 jpg->DataImg[lbInc]= jpg->DataImg[lbInc]&mask; 00386 00387 lbInc+=1; 00388 if (lbInc>(jpg->lSof.Himg*jpg->lSof.Wimg-1)) return 1; 00389 00390 if (jpg->lSos.SpectralSelStart==7) // si spectral 00391 lPredicted=( jpg->DataImg[lbInc-1]+ jpg->DataImg[lbInc-jpg->lSof.Wimg])>>1; 00392 else 00393 lPredicted= jpg->DataImg[lbInc-1]; 00394 } 00395 while (!jpg->MarkerFound) 00396 { 00397 ClbJpegReadBit(jpg); // skip bits restant avant restart marker 00398 } 00399 } 00400 } 00401 return 1; 00402 } 00403 00404 static int ClbJpegDecodeDiff(ClbJpeg *jpg) 00405 { 00406 int lInput; 00407 int lInputBits; 00408 int lHufVal; 00409 int lDiff; 00410 int lI; 00411 int resultat; 00412 lHufVal = 666; 00413 lInput = 0; 00414 lInputBits = 0; 00415 00416 00417 while (1) 00418 { 00419 lInputBits+=1; 00420 lInput=(lInput<<1)+ClbJpegReadBit(jpg); 00421 if (jpg->RawDHT[lInputBits]!=0) 00422 { 00423 for(lI=jpg->RawDHTstart[lInputBits];lI<(jpg->RawDHTstart[lInputBits]+jpg->RawDHT[lInputBits]);lI++) 00424 { 00425 if (lInput==jpg->lHuffTable[lI].HufCode) 00426 lHufVal=jpg->lHuffTable[lI].HufVal; 00427 } 00428 } 00429 if (lInputBits>=jpg->MaxHuffSz) 00430 lHufVal=jpg->MaxHuffVal; 00431 if (lHufVal<255) break; 00432 } 00433 if (lHufVal==0) resultat= 0; 00434 00435 if ( (lHufVal>0) && (lHufVal<16)) 00436 { 00437 lDiff=0; 00438 if( ClbJpegReadBit(jpg)==1) 00439 { 00440 for (lI=1;lI<lHufVal;lI++) 00441 { 00442 lDiff=(lDiff<<1)+ClbJpegReadBit(jpg); 00443 } 00444 00445 resultat= (lDiff+(1<<(lHufVal-1))); 00446 } 00447 else 00448 { 00449 for (lI=1;lI<lHufVal;lI++) 00450 lDiff=(lDiff<<1)+1-ClbJpegReadBit(jpg); 00451 resultat= -(lDiff+(1<<(lHufVal-1))); 00452 } 00453 } 00454 00455 return resultat; 00456 00457 }

Generated on Wed Oct 19 09:28:32 2005 for SIMRI3D by doxygen 1.3.7