#include"image.h" #include int Image::IsTiff(FILE *fl) { unsigned short int tmps; if(!fl) GENNFERR("(Is Tiff)Invalid File"); int fpos=ftell(fl); fread(&tmps,2,1,fl); // read data type if(tmps==0x4949 || tmps==0x4d4d) { fread(&tmps,2,1,fl); // read data type fseek(fl,fpos,SEEK_SET); if(tmps==0x2a) return 1; } fseek(fl,fpos,SEEK_SET); return 0; } void Image::LoadTiff(char *str) { FILE *fl=fopen(str,"rb"); if(!fl) { char tfn[MAX_PATH*2]; strcpy(tfn,"Cannont open TIF file for reading:"); strcat(tfn,str); GENNFERR(tfn); } LoadTiff(fl); fclose(fl); strcpy(fname,str); } void Image::SaveTiff(char *str) { FILE *fl=fopen(str,"wb"); if(!fl) { char tfn[200]; strcpy(tfn,"Cannont open TIF file for Writeing:"); strcat(tfn,str); GENNFERR(tfn); } SaveTiff(fl); fclose(fl); strcpy(fname,str); } //>>>>>>>>Tiff void Image::LoadTiff(FILE *fl) { unsigned char *odata,*cdata; long int *sloc,*bps; long int i,initpos,fpos,tmpl,comp=999; long int strip,rps,samples; short int abts,rbts,gbts,bbts,tmps,nof,nos; long unsigned int *codetable; unsigned char *FileBuf; int dflag=0; abts=0; initpos=ftell(fl); //get file position fread(&tmps,2,1,fl); // read data type switch(tmps) { case 0x4949: break; //LSB case 0x4D4D: GENNFERR("Tiff Error-Mac Images unsupported"); break; //MSB default: GENNFERR("Tiff Error-Undefined Byte ordering"); } fread(&tmps,2,1,fl); // read version number if(tmps!=0x2a) GENNFERR("Tiff Error-Wrong Version"); //wrong version fread(&tmpl,4,1,fl); // read offset to directory fseek(fl,tmpl+initpos,SEEK_SET); // setposition fread(&nof,2,1,fl); // read number of fieldss for(i=0;i3) fread(&abts,2,1,fl); // alpha bits ABCD :) break; case 259: //get compression scheme comp=field.offset; if(comp!=1 && comp!=5) GENNFERR("Tiff Error-Unsupported Compression"); //for uncompressed break; case 262: //get photometric interp if(field.offset!=2) GENNFERR("Tiff Error-Image Not RGB"); // not RGB break; case 273: //get striplocation nos=(short int)field.lenght; sloc=new long int[nos]; if(nos<=1) sloc[0]=(short unsigned int)field.offset; else { fseek(fl,initpos+field.offset,SEEK_SET); // setposition if(field.type==3) fread(sloc,2*nos,1,fl); else if(field.type==4) fread(sloc,4*nos,1,fl); else GENNFERR("Tiff Error"); } break; case 277: //samples per pixel samples=field.offset; switch(samples) { case 4: case 3: case 2: itype=ITYPE_RGB; Bpp=8*samples; break; default: GENNFERR("Tiff Error-Invalid Pixel Format"); } break; case 278: rps=field.offset; break; //rowsperstrip case 279: bps=new long int[nos]; if(nos<=1) bps[0]=(short unsigned int)field.offset; else { fseek(fl,initpos+field.offset,SEEK_SET); // setposition fread(bps,nos*4,1,fl); } break; //bytesperstrip case 282: break; //pixels per xres case 283: break; //pixels per yres case 284: //sampleplanes if(field.offset!=1) GENNFERR("Tiff Error-Not Single Plane"); //not single planer break; case 296: break; //resolution unit case 317: //predictor dflag=field.offset; if(dflag!=1 && dflag!=2) GENNFERR("Tiff Error-Invalid Diff"); //uses differtiation break; } //end of switch fseek(fl,fpos,SEEK_SET); // resetposition } //end of number of fields if(abts) Mask.Set(0x000000ff,0x0000ff00,0x00ff0000,0xff000000); else Mask.Set(0x000000ff,0x0000ff00,0x00ff0000,0) ; IAlloc(); cdata=Lock(); odata=cdata; //begin decompression codetable=new DWORD[4096*4]; if(comp==5) for(strip=0;strip>3)*xlen; fseek(fl,initpos+sloc[strip],SEEK_SET); //goto strip FileBuf= new unsigned char[bps[strip]]; fread(FileBuf,bps[strip],1,fl); int fbufcnt=0; mask=(1<0) { //do lzw while(totalbits>(totalbits-bitlen))&mask; //get the code totalbits-=bitlen; if (newcode==257) endflag=0; else // end code if (newcode==256) {bitlen=9; currentcode=257; mask=(1<currentcode) GENNFERR("Tiff Decompression Error"); //check for bad code codetable[currentcode]=offset; for(li=codetable[newcode];li<=codetable[newcode+1];li++) cdata[offset++]=cdata[li]; bytecount-=codetable[newcode+1]-codetable[newcode]+1; codetable[currentcode+1]=offset; } //end of else >=256 if(((DWORD)++currentcode)==(DWORD)1<>3),bps[strip],1,fl); } CorrectPitch(); //adjust data for pitch. if(dflag==2) UnDifference(); UnLock(); delete codetable; delete bps; delete sloc; } //end of load Tiff Member //>>>>>>>>>>>>>>>>>> File Writers //>>>>>>>>Tiff void Image::SaveTiff(FILE *fl) { int i,initpos,pos,cpos,tmpl,btotal,samples; int strip,bps,slc,byps,nos,res,lps,bpstrip; int *sloc,*bpsl; unsigned char *cpydata; WORD tmps; short int *nptable; DWORD *codetable; struct { short int tag,type; long int lenght,offset;} field; int ep,fof,evl,ocd,cnt; unsigned char *ptmp,*p2; int *iptmp,*ip2; //fname=fl.GetFileName(); if(Mask.GetAMask()) MaskTo(RGBMask(0x0000ff,0x00ff00,0xff0000,0xff000000)); else MaskTo(RGBMask(0x0000ff,0x00ff00,0xff0000)); if(!IsData()) GENNFERR("(SaveTiff)Image does not contain data"); BYTE *tmpbuf; if(Pitch==xlen*(Bpp>>3)) cpydata=Lock(); else DePitch(cpydata=tmpbuf=new BYTE[xlen*ylen*(Bpp>>3)]); initpos=ftell(fl); samples=Bpp>>3; /* switch(Bpp) { case 2: samples=2; break; case 3: samples=3; break; default : return 12; } */ lps=0x4000/(xlen*samples); bpstrip=lps*xlen*samples; nos=ylen/lps; if(ylen%lps) nos++; btotal=xlen*ylen*samples; fwrite("II",2,1,fl); //write lsb code tmps=0x2a; fwrite(&tmps,2,1,fl); // write version number tmpl=8; fwrite(&tmpl,4,1,fl); // write offset to directory tmps=15; fwrite(&tmps,2,1,fl); // write number of fieldss field.tag=254; field.type=4; field.lenght=1; field.offset=0; fwrite(&field,12,1,fl); //write file code field.tag=256; field.type=4; field.lenght=1; field.offset=xlen; fwrite(&field,12,1,fl); //write file xlen field.tag=257; field.type=4; field.lenght=1; field.offset=ylen; fwrite(&field,12,1,fl); //write file ylen bps=ftell(fl); field.tag=258; field.type=3; field.lenght=3; field.offset=999; fwrite(&field,12,1,fl); //write bit per sample field.tag=259; field.type=3; field.lenght=1; field.offset=5; fwrite(&field,12,1,fl); //write compression scheme(LZW) field.tag=262; field.type=3; field.lenght=1; field.offset=2; fwrite(&field,12,1,fl); //write photometric RGB slc=ftell(fl); field.tag=273; field.type=4; field.lenght=nos; field.offset=999; fwrite(&field,12,1,fl); //write striplocation field.tag=277; field.type=3; field.lenght=1; field.offset=samples; fwrite(&field,12,1,fl); //write samples perpixel field.tag=278; field.type=4; field.lenght=1; field.offset=lps; fwrite(&field,12,1,fl); //write rows per strip byps=ftell(fl); field.tag=279; field.type=4; field.lenght=nos; field.offset=999; fwrite(&field,12,1,fl); //write bytes per strip res=ftell(fl); field.tag=282; field.type=5; field.lenght=1; field.offset=999; fwrite(&field,12,1,fl); //write planer field.tag=283; field.type=5; field.lenght=1; field.offset=999; fwrite(&field,12,1,fl); //write xres field.tag=284; field.type=3; field.lenght=1; field.offset=1; fwrite(&field,12,1,fl); //write yres field.tag=296; field.type=3; field.lenght=1; field.offset=2; fwrite(&field,12,1,fl); //write resolution field.tag=317; field.type=3; field.lenght=1; field.offset=1; fwrite(&field,12,1,fl); //write predictor tmpl=0; fwrite(&tmpl,4,1,fl); // write bits persample pos=ftell(fl); samples=Bpp>>3; tmps=(WORD)Mask.GetRBits(); fwrite(&tmps,2,1,fl); // write red bits persample tmps=(WORD)Mask.GetGBits(); fwrite(&tmps,2,1,fl); // write green bits persample tmps=(WORD)Mask.GetBBits(); fwrite(&tmps,2,1,fl); // write blue bits persample if(Mask.GetAMask()) {tmps=(WORD)Mask.GetABits(); fwrite(&tmps,2,1,fl); }// write alpha bits persample cpos=ftell(fl); fseek(fl,bps,SEEK_SET); // setposition field.tag=258; field.type=3; field.lenght=3; field.offset=pos-initpos; if(Mask.GetAMask()) field.lenght++; fwrite(&field,12,1,fl); //write bit per sample fseek(fl,cpos,SEEK_SET); // resetposition pos=ftell(fl); tmpl=576; fwrite(&tmpl,4,1,fl); tmpl=5; fwrite(&tmpl,4,1,fl); tmpl=72; fwrite(&tmpl,4,1,fl); tmpl=1; fwrite(&tmpl,4,1,fl); cpos=ftell(fl); fseek(fl,res,SEEK_SET); // setposition field.tag=282; field.type=5; field.lenght=1; field.offset=pos-initpos; fwrite(&field,12,1,fl); //xres field.tag=283; field.type=5; field.lenght=1; field.offset+=8; fwrite(&field,12,1,fl); //yres fseek(fl,cpos,SEEK_SET); // resetposition sloc=new int[nos]; bpsl=new int[nos]; nptable=new short int[4096]; codetable=new DWORD[4096]; for(strip=0;stripbtotal) bytecount=btotal; else btotal-=bytecount; sloc[strip]=ftell(fl)-initpos; for(i=0;i<4096;i++) nptable[i]=-1; while (endflag) { while(totalbits>=8) { tbyte=(unsigned char)(databuf>>(totalbits-8))&0xff; fwrite(&tbyte,1,1,fl); totalbits-=8;} codetable[currentcode]=offset; ptmp=cpydata+offset; iptmp=(int *)ptmp; match=0; ocd=nptable[*ptmp]; // get the starting reference code while(ocd!=-1 && !match) // if there is a prior code and no match { fof=codetable[ocd]; evl=(codetable[ocd+1]-fof)+1; p2=cpydata+fof; ip2=(int *)p2; if (evl<=bytecount) { ep=evl>>2; //dword method for(cnt=0;cnt=0xffe) //send clear code { databuf=(databuf<=8) {tbyte=(unsigned char)(databuf>>(totalbits-8))&0xff; fwrite(&tbyte,1,1,fl); totalbits-=8;} databuf=(databuf<=8) {tbyte=(unsigned char)(databuf>>(totalbits-8))&0xff; fwrite(&tbyte,1,1,fl); totalbits-=8;} tbyte=(unsigned char)databuf<<(8-totalbits); fwrite(&tbyte,1,1,fl); } if(((DWORD)++currentcode)==(DWORD)1<1) { pos=ftell(fl); for(i=0;i>3))) UnLock(); else delete tmpbuf; MaskFrom(RGBMask(0x0000ff,0x00ff00,0xff0000)); delete nptable; delete codetable; delete sloc; delete bpsl; }