home *** CD-ROM | disk | FTP | other *** search
- /*
- * dispatch.c
- */
-
- #include "classbase.h"
- #include "TIFF.h"
- #include "TIFFTags.h"
- #include <libraries/xpksub.h>
-
- #define DB(x) x;
- #define DC(x) ;
- #define DP(x) ;
-
- #define SWAPW(a) (Rev ? (WORD)(((UWORD)a>>8)+((((UWORD)a&0xff)<<8))) : a)
- #define SWAPU(a) (Rev ? (UWORD)(((UWORD)a>>8)+((((UWORD)a&0xff)<<8))) : a)
- #define SWAPL(a) (Rev ? (LONG)(((ULONG)a>>24)+(((ULONG)a&0xff0000)>>8)+(((ULONG)a&0xff00)<<8)+(((ULONG)a&0xff)<<24)): a)
-
- void ASM ReadShorts(REG (a0) BPTR fh, REG (a1) USHORT *buffer, REG (a2) TIFFTagItem *tag,REG (a6) struct ClassBase *cb);
- void ASM ReadLongs(REG (a0) BPTR fh, REG (a1) ULONG *buffer, REG (a2) TIFFTagItem *tag,REG (a6) struct ClassBase *cb);
- void ASM ReadRational(REG (a0) BPTR fh, REG (a1) struct Rational *buffer, REG (a2) TIFFTagItem *tag,REG (a6) struct ClassBase *cb);
- void ASM ReadBytes(REG (a0) BPTR fh, REG (a1) UBYTE *buffer, REG (a2) TIFFTagItem *tag,REG (a6) struct ClassBase *cb);
- int ASM UnPackLZW(REG (a0) UBYTE *source, REG (a1) UBYTE *dest, REG (d0) int len, REG (a6) struct ClassBase *cb);
- void ASM InitializeStringTable(REG (a6) struct ClassBase *cb);
- void ASM GetNextCode(REG (a6) struct ClassBase *cb);
- void ASM AddStringToTable(REG (d0) int code,REG (d1) int newchar,REG (a6) struct ClassBase *cb);
- void ASM WriteString(REG (d0) int code,REG (a6) struct ClassBase *cb);
- void ASM IsInTable(REG (d0) int code,REG (a6) struct ClassBase *cb);
- void ASM Chunky2Planar(REG (d0) int width,REG (a0) UBYTE *buffer,REG (a1) UBYTE *tempbmp);
-
- #define TAGVAL(a,b) (SWAPW(a.Type)==TT_BYTE ? a.CValue[b] : \
- (SWAPW(a.Type)==TT_SHORT ? SWAPW(a.SValue[b]) : \
- (SWAPW(a.Type)==TT_LONG ? SWAPL(a.LValue) : \
- ~0)))
-
- char Rev=0; /* flag for reverse byte order */
-
- void *pool,*poolchip; /* memory pool for allocations */
-
- struct BitMapHeader *bmhd;
-
- struct StringEntry
- {
- struct StringEntry *OldCode;
- UWORD StringLen;
- UBYTE FirstChar;
- UBYTE LastChar;
- } *StringTable;
-
- TIFFBasicFields BF={
- 2, /* GrayResponseUnit */
- 0, /* NewSubfileType */
- 0, /* PhotometricInterpretation */
- CHUNKY, /* PlanarConfiguration */
- NO_PREDICTOR, /* Predictor */
- INCH, /* ResolutionUnit */
- 1, /* SamplesPerPixel */
- NO_COMPRESSION, /* Compression */
- {1}, /* BitsPerSample */
- NULL, /* ColorMap */
- NULL, /* ColorResponseCurve */
- NULL, /* GrayResponseCurve */
- 0, /* ImageLength */
- 0, /* ImageWidth */
- (USHORT)~0, /* RowsPerStrip */
- NULL, /* StripByteCounts */
- NULL, /* StripOffsets */
- };
-
- TIFFInformationFields IF={NULL,NULL,NULL,NULL,NULL,NULL,};
-
- TIFFFaxFields FF={0,0};
-
- TIFFDocumentFields DF={
- NULL, /* DocumentName */
- NULL, /* PageName */
- LINE_ART, /* Threshhold */
- TOPLEFT, /* Orientation */
- 0, /* CellLength */
- 0, /* CellWidth */
- MSB_FIRST, /* FillOrder */
- 0,0, /* PageNumber */
- {0xffff,0xffff,0xffff,0xffff,
- 0xffff,0xffff,0xffff,0xffff}, /* MaxSampleValue */
- {0,0,0,0,0,0,0,0}, /* MinSampleValue */
- };
-
- /*****************************************************************************/
-
- struct RGBQuad
- {
- UBYTE rgbBlue;
- UBYTE rgbGreen;
- UBYTE rgbRed;
- UBYTE rgbReserved;
- };
-
- #define QSIZE (sizeof (struct RGBQuad))
-
- /*****************************************************************************/
-
- BOOL ASM GetTIFF (REG (a6) struct ClassBase *cb, REG (a0) Class * cl, REG (a2) Object * o, REG (a1) struct TagItem * attrs);
- BOOL ASM convert(REG (a6) struct ClassBase *cb,REG (a0) BPTR fh, REG (a1) Object * o);
-
- ULONG setdtattrs (struct ClassBase *cb, Object * o, ULONG data,...)
- {
- return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
- }
-
- /*****************************************************************************/
-
- ULONG getdtattrs (struct ClassBase *cb, Object * o, ULONG data,...)
- {
- return (GetDTAttrsA (o, (struct TagItem *) & data));
- }
-
- /*****************************************************************************/
-
- Class *initClass (struct ClassBase *cb)
- {
- Class *cl;
-
- if (cl = MakeClass (TIFFDTCLASS, PICTUREDTCLASS, NULL, NULL, 0L))
- {
- cl->cl_Dispatcher.h_Entry = Dispatch;
- cl->cl_UserData = (ULONG) cb;
- AddClass (cl);
- }
-
- return (cl);
- }
-
- /*****************************************************************************/
-
- ULONG ASM Dispatch (REG (a0) Class * cl, REG (a2) Object * o, REG (a1) Msg msg)
- {
- struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
- ULONG retval;
-
- switch (msg->MethodID)
- {
- case OM_NEW:
- if (retval = DoSuperMethodA (cl, o, msg))
- {
- DB (KPrintF ("OM_NEW\n"));
-
- if (!GetTIFF (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList))
- {
- CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
- return NULL;
- }
- }
- break;
-
- /* Let the superclass handle everything else */
- default:
- retval = (ULONG) DoSuperMethodA (cl, o, msg);
- break;
- }
-
- return (retval);
- }
-
- BOOL ASM GetTIFF (REG (a6) struct ClassBase *cb, REG (a0) Class * cl, REG (a2) Object * o, REG (a1) struct TagItem * attrs)
- {
- TIFFImageFileHeader ifh;
- TIFFTagItem tti;
- short NumTags;
- LONG i;
- STRPTR title;
- BPTR fh;
- BOOL flag=FALSE;
-
- title = (STRPTR) GetTagData (DTA_Name, NULL, attrs);
- setdtattrs (cb, o,DTA_ObjName,title,TAG_DONE);
-
- DB (KPrintF ("GetTIFF %s\n",title));
-
- pool=CreatePool(MEMF_CLEAR,8192,8192);
- if(!pool) return FALSE;
-
- if ((getdtattrs (cb, o, DTA_Handle, &fh, PDTA_BitMapHeader, &bmhd, TAG_DONE) == 2) && fh)
- {
-
- DB (KPrintF ("GetDTAttrs\n"));
-
- Seek (fh, 0L, OFFSET_BEGINNING);
-
- /* read image file header */
-
- if (Read (fh, &ifh, TIFHSIZE) == TIFHSIZE)
- {
- if (ifh.ByteOrder == 'II')
- {
- DB (KPrintF ("reverse byte order\n"));
- Rev=1;
- }
- else if (ifh.ByteOrder == 'MM')
- {
- DB (KPrintF ("normal byte order\n"));
- Rev=0;
- }
- else
- SetIoErr (ERROR_OBJECT_WRONG_TYPE);
-
- DB (KPrintF ("Version %lx %lx\n",(long)ifh.Version,(long)SWAPW(ifh.Version)));
- DB (KPrintF ("Offset %lx %lx\n",ifh.Offset,SWAPL(ifh.Offset)));
-
- }
- else
- {
- DB (KPrintF ("couldn't read information\n"));
- DeletePool(pool);
- return FALSE;
- }
-
- Seek (fh, SWAPL(ifh.Offset), OFFSET_BEGINNING);
-
- /* read image file directory */
-
- if (Read (fh, &NumTags, sizeof(short)) == sizeof(short))
- {
- NumTags=SWAPW(NumTags);
- for(i=0;i<NumTags;i++)
- {
- if (Read (fh, &tti, TTISIZE) == TTISIZE)
- {
-
- DB ( KPrintF("%ld:\n",(long)SWAPW(tti.Tag)));
- tti.Count=SWAPL (tti.Count);
- switch (SWAPW (tti.Tag))
- {
- case TT_NewSubfileType:
- BF.NewSubfileType=TAGVAL(tti,0);
- DB ( KPrintF("tag NewSubfileType\n"));
- break;
- case TT_SubfileType:
- switch(TAGVAL(tti,0))
- {
- case REDUCED_RESOLUTION:
- BF.NewSubfileType|=REDUCED;
- break;
- case MULTI_PAGE:
- BF.NewSubfileType|=MULTIPAGE;
- break;
- }
- DB ( KPrintF("tag SubfileType\n"));
- break;
- case TT_ImageWidth:
- bmhd->bmh_Width=BF.ImageWidth=TAGVAL(tti,0);
- DB ( KPrintF("ImageWidth %ld\n",BF.ImageWidth));
- break;
- case TT_ImageLength:
- bmhd->bmh_Height=BF.ImageLength=TAGVAL(tti,0);
- DB ( KPrintF("ImageLength %ld\n",BF.ImageLength));
- if(BF.RowsPerStrip==(USHORT)~0)
- BF.RowsPerStrip=BF.ImageLength;
- break;
- case TT_BitsPerSample:
- if(tti.Count>2)
- ReadShorts(fh,BF.BitsPerSample,&tti,cb);
- else
- BF.BitsPerSample[0]=TAGVAL(tti,0);
- if(tti.Count==2)
- BF.BitsPerSample[1]=TAGVAL(tti,1);
- if(DF.MaxSampleValue[0]==~0)
- {
- int i;
- for(i=0;i<8;i++)
- DF.MaxSampleValue[i]=(2<<BF.BitsPerSample[i])-1;
- }
- DB ( KPrintF("BitPerSample %ld %lx\n",(long)BF.BitsPerSample[0],(long)tti.LValue));
- break;
- case TT_Compression:
- BF.Compression=TAGVAL(tti,0);
- DB ( KPrintF("Compression %ld\n",(long)BF.Compression));
- break;
- case TT_PhotometricInterpretation:
- BF.PhotometricInterpretation=TAGVAL(tti,0);
- DB ( KPrintF("PhotometricInterpretation %ld\n",(long)BF.PhotometricInterpretation));
- break;
- case TT_Threshholding:
- DF.Threshholding=TAGVAL(tti,0);
- DB ( KPrintF("Threshholding %ld\n",(long)DF.Threshholding));
- break;
- case TT_CellWidth:
- DF.CellWidth=TAGVAL(tti,0);
- DB ( KPrintF("CellWidth %ld\n",(long)DF.CellWidth));
- break;
- case TT_CellLength:
- DF.CellLength=TAGVAL(tti,0);
- DB ( KPrintF("CellLength %ld\n",(long)DF.CellLength));
- break;
- case TT_FillOrder:
- DF.FillOrder=TAGVAL(tti,0);
- DB ( KPrintF("FillOrder %ld\n",(long)DF.FillOrder));
- break;
- case TT_DocumentName:
- DF.DocumentName=AllocPooled(pool,tti.Count);
- if(!DF.DocumentName) goto abort;
- ReadBytes(fh,DF.DocumentName,&tti,cb);
- DB ( KPrintF("DocumentName %s\n",DF.DocumentName));
- break;
- case TT_ImageDescription:
- IF.ImageDescription=AllocPooled(pool,tti.Count);
- if(!IF.ImageDescription) goto abort;
- ReadBytes(fh,IF.ImageDescription,&tti,cb);
- DB ( KPrintF("ImageDescription %s\n",IF.ImageDescription));
- break;
- case TT_Make:
- IF.Make=AllocPooled(pool,tti.Count);
- if(!IF.Make) goto abort;
- ReadBytes(fh,IF.Make,&tti,cb);
- DB ( KPrintF("Make %s\n",IF.Make));
- break;
- case TT_Model:
- IF.Model=AllocPooled(pool,tti.Count);
- if(!IF.Model) goto abort;
- ReadBytes(fh,IF.Model,&tti,cb);
- DB ( KPrintF("Model %s\n",IF.Model));
- break;
- case TT_StripOffsets:
- BF.StripOffsets=AllocPooled(pool,tti.Count*sizeof(long));
- DB ( KPrintF("StripOffsets %ld\n",(long)tti.Count));
- if(!BF.StripOffsets) goto abort;
- ReadLongs(fh,BF.StripOffsets,&tti,cb);
- break;
- case TT_Orientation:
- DF.Orientation=TAGVAL(tti,0);
- DB ( KPrintF("Orientation %ld\n",(long)DF.Orientation));
- break;
- case TT_SamplesPerPixel:
- BF.SamplesPerPixel=TAGVAL(tti,0);
- DB ( KPrintF("SamplePerPixel %ld\n",(long)BF.SamplesPerPixel));
- break;
- case TT_RowsPerStrip:
- BF.RowsPerStrip=TAGVAL(tti,0);
- DB ( KPrintF("RowsPerStrip %ld\n",(long)BF.RowsPerStrip));
- break;
- case TT_StripByteCounts:
- BF.StripByteCounts=AllocPooled(pool,tti.Count*sizeof(long));
- DB ( KPrintF("StripByteCounts %ld\n",(long)tti.Count));
- if(!BF.StripByteCounts) goto abort;
- ReadLongs(fh,BF.StripByteCounts,&tti,cb);
- break;
- case TT_MaxSampleValue:
- DB ( KPrintF("MaxSampleValue %ld\n",(long)tti.Count));
- ReadShorts(fh,DF.MaxSampleValue,&tti,cb);
- break;
- case TT_MinSampleValue:
- DB ( KPrintF("MinSampleValue %ld\n",(long)tti.Count));
- ReadShorts(fh,DF.MinSampleValue,&tti,cb);
- break;
- case TT_XResolution:
- ReadRational(fh,&BF.XResolution,&tti,cb);
- DB ( KPrintF("XResolution %ld / %ld\n",(long)BF.XResolution.Numerator,BF.XResolution.Denominator));
- break;
- case TT_YResolution:
- ReadRational(fh,&BF.YResolution,&tti,cb);
- DB ( KPrintF("YResolution %ld / %ld\n",(long)BF.YResolution.Numerator,BF.YResolution.Denominator));
- break;
- case TT_PlanarConfiguration:
- BF.PlanarConfiguration=TAGVAL(tti,0);
- DB ( KPrintF("PlanarConfiguration %ld\n",(long)BF.PlanarConfiguration));
- break;
- case TT_PageName:
- DF.PageName=AllocPooled(pool,tti.Count);
- if(!DF.PageName) goto abort;
- ReadBytes(fh,DF.PageName,&tti,cb);
- DB ( KPrintF("PageName %s\n",DF.PageName));
- break;
- case TT_XPosition:
- ReadRational(fh,&DF.XPosition,&tti,cb);
- DB ( KPrintF("XPosition %ld / %ld\n",(long)DF.XPosition.Numerator,DF.XPosition.Denominator));
- break;
- case TT_YPosition:
- ReadRational(fh,&DF.XPosition,&tti,cb);
- DB ( KPrintF("YPosition %ld / %ld\n",(long)DF.YPosition.Numerator,DF.YPosition.Denominator));
- break;
- case TT_GrayResponseUnit:
- BF.GrayResponseUnit=TAGVAL(tti,0);
- DB ( KPrintF("GrayResponseUnit %d\n",(int)BF.GrayResponseUnit));
- break;
- case TT_GrayResponseCurve:
- BF.GrayResponseCurve=AllocPooled(pool,tti.Count*sizeof(short));
- DB ( KPrintF("GrayResponseCurve size %ld\n",(long)tti.Count));
- if(!BF.GrayResponseCurve) goto abort;
- ReadShorts(fh,BF.GrayResponseCurve,&tti,cb);
- break;
- case TT_Group3Options:
- FF.Group3Options=TAGVAL(tti,0);
- DB ( KPrintF("Group3Options %x\n",(int)FF.Group3Options));
- break;
- case TT_Group4Options:
- FF.Group4Options=TAGVAL(tti,0);
- DB ( KPrintF("Group4Options %x\n",(int)FF.Group4Options));
- break;
- case TT_ResolutionUnit:
- BF.ResolutionUnit=TAGVAL(tti,0);
- DB ( KPrintF("ResolutionUnit %ld\n",(long)BF.ResolutionUnit));
- break;
- case TT_PageNumber:
- DB ( KPrintF("PageNumber\n"));
- ReadShorts(fh,DF.PageNumber,&tti,cb);
- DB ( KPrintF(" %d %d\n",(int)DF.PageNumber[0],(int)DF.PageNumber[1]));
- break;
- case TT_ColorResponseCurves:
- BF.ColorResponseCurves=AllocPooled(pool,tti.Count*sizeof(short));
- DB ( KPrintF("ColorResponseCurves size %ld\n",(long)tti.Count));
- if(!BF.ColorResponseCurves) goto abort;
- ReadShorts(fh,BF.ColorResponseCurves,&tti,cb);
- break;
- case TT_Software:
- IF.Software=AllocPooled(pool,tti.Count);
- DB ( KPrintF("Software %s\n",IF.Software));
- if(!IF.Software) goto abort;
- ReadBytes(fh,IF.Software,&tti,cb);
- break;
- case TT_DateTime:
- DB ( KPrintF("DateTime %s\n",IF.DateTime));
- ReadBytes(fh,IF.DateTime,&tti,cb);
- break;
- case TT_Artist:
- IF.Artist=AllocPooled(pool,tti.Count);
- DB ( KPrintF("Artist %s\n",IF.Artist));
- if(!IF.Artist) goto abort;
- ReadBytes(fh,IF.Artist,&tti,cb);
- break;
- case TT_HostComputer:
- IF.HostComputer=AllocPooled(pool,tti.Count);
- DB ( KPrintF("HostComputer %s\n",IF.HostComputer));
- if(!IF.HostComputer) goto abort;
- ReadBytes(fh,IF.HostComputer,&tti,cb);
- break;
- case TT_Predictor:
- BF.Predictor=TAGVAL(tti,0);
- DB ( KPrintF("Predictor %ld\n",(long)BF.Predictor));
- break;
- case TT_WhitePoint:
- DB ( KPrintF("tag WhitePoint\n"));
- break;
- case TT_PrimaryChromaticities:
- DB ( KPrintF("tag PrimaryChromaticities\n"));
- break;
- case TT_ColorMap:
- BF.ColorMap=AllocPooled(pool,tti.Count*sizeof(short));
- DB ( KPrintF("ColorMap size %ld\n",(long)tti.Count));
- if(!BF.ColorMap) goto abort;
- ReadShorts(fh,BF.ColorMap,&tti,cb);
- break;
- case TT_InkSet:
- DB ( KPrintF("tag InkSet\n"));
- break;
- case TT_InkNames:
- DB ( KPrintF("tag InkNames\n"));
- break;
- case TT_TargetPrinter:
- DB ( KPrintF("tag TargetPrinter\n"));
- break;
-
- case TT_JPEGProc:
- DB ( KPrintF("tag JPEGProc\n"));
- break;
- case TT_JPEGInterchangeFormat:
- DB ( KPrintF("tag JPEGInterchangeFormat:\n"));
- break;
- case TT_JPEGInterchangeFormatLength:
- DB ( KPrintF("tag JPEGInterchangeFormatLength\n"));
- break;
- case TT_JPEGLosslessPredictors:
- DB ( KPrintF("tag JPEGLosslessPredictors\n"));
- break;
- case TT_JPEGQTables:
- DB ( KPrintF("tag JPEGQTables\n"));
- break;
- case TT_JPEGDCTables:
- DB ( KPrintF("tag JPEGDCTables\n"));
- break;
- case TT_JPEGACTables:
- DB ( KPrintF("tag JPEGACTables\n"));
- break;
-
- case TT_YCbCrCoefficents:
- DB ( KPrintF("tag YCbCrCoefficents\n"));
- break;
- case TT_YCbCrSubSampling:
- DB ( KPrintF("tag YCbCrSubSampling\n"));
- break;
- case TT_YCbCrPositioning:
- DB ( KPrintF("tag YCbCrPositioning\n"));
- break;
- default:
- DB (KPrintF ("Unknown tag %ld\n", (long)SWAPW (tti.Tag)));
- break;
- }
- }
- else
- {
- DB (KPrintF ("couldn't read information\n"));
- DeletePool(pool);
- return FALSE;
- }
- }
- }
- }
-
- flag=convert(cb,fh,o);
-
- abort:
- DeletePool(pool);
- return flag;
- }
-
- /* converts the image in BitMap format */
-
- BOOL ASM convert(REG (a6) struct ClassBase *cb,REG (a0) BPTR fh, REG (a1) Object * o)
-
- {
- ULONG modeid = HIRES_KEY;
- struct RastPort rp;
- LONG i, j, k, l, m;
- struct BitMap *bm=NULL,tbm;
- UBYTE *buffer,*buffer3,*ErrRed,*ErrGreen,*ErrBlue;
- LONG depth,ncolors;
- struct ColorRegister *cmap;
- LONG *cregs;
-
- DB (KPrintF ("Convert:\n"));
-
- DB ( KPrintF("BitPerSample %ld \n",(long)BF.BitsPerSample[0]));
- depth=BF.BitsPerSample[0];
-
- DB ( KPrintF("depth %ld \n",(long)depth));
- ncolors=1<<depth;
-
- DB (KPrintF ("NColors %ld\n",ncolors));
-
- setdtattrs (cb, o, PDTA_NumColors, ncolors, TAG_DONE);
-
- getdtattrs (cb, o,
- PDTA_ColorRegisters, (ULONG)&cmap,
- PDTA_CRegs, &cregs,
- TAG_DONE);
-
- switch(BF.Compression)
- {
- case NO_COMPRESSION:
- break;
- case LZW:
-
- /* allocate LZW table */
-
- StringTable=AllocPooled(pool,sizeof(struct StringEntry)*4096);
- if(StringTable==NULL)
- {
- DB (KPrintF ("Unable to allocate LZW string table\n"));
- goto abort;
- }
-
- /* initialize first entries for lzw decompression table */
-
- for(i=0;i<256;i++)
- {
- StringTable[i].StringLen=1;
- StringTable[i].FirstChar=StringTable[i].LastChar=i;
- }
- break;
- default:
- DB (KPrintF ("Unsupported Compression\n"));
- goto abort;
- }
-
- switch(BF.PhotometricInterpretation)
- {
- case BILEVEL_ZERO_IS_WHITE:
- for(i=0;i<ncolors;i++)
- {
- /* Set the master color table */
- cmap->red = cmap->green = cmap->blue = (0xff/((1<<BF.BitsPerSample[0])-1))*(ncolors-i-1);
-
- /* Set the color table used for remapping */
- cregs[i*3+0] = cregs[i*3+1] = cregs[i*3+2] = cmap->blue<<24;
- cmap++;
- }
- break;
- case BILEVEL_ZERO_IS_BLACK:
- for(i=0;i<ncolors;i++)
- {
- /* Set the master color table */
- cmap->red = cmap->green = cmap->blue = (0xff/((1<<BF.BitsPerSample[0])-1))*i;
-
- /* Set the color table used for remapping */
- cregs[i*3+0] = cregs[i*3+1] = cregs[i*3+2] = cmap->blue<<24;
- cmap++;
- }
- break;
- case TRUE_COLOR_RGB:
- for(i=0;i<ncolors;i++)
- {
- /* Set the master color table */
- cmap->red = i & 0xe0;
- cmap->green = (i<<3) & 0xe0;
- cmap->blue = i<<6;
-
- /* Set the color table used for remapping */
- cregs[i*3+0] = cmap->red << 24;
- cregs[i*3+1] = cmap->green << 24;
- cregs[i*3+2] = cmap->blue << 24;
- cmap++;
- }
-
- /* allocate buffer for Floyd-Steinberg dithering */
- ErrRed=AllocPooled(pool,BF.ImageWidth+1);
- ErrGreen=AllocPooled(pool,BF.ImageWidth+1);
- ErrBlue=AllocPooled(pool,BF.ImageWidth+1);
- break;
- case COLOR_MAPPED_RGB:
- DB (KPrintF ("Color Mapped depth=%ld\n",depth));
- for(i=0;i<ncolors;i++)
- {
- /* Set the master color table */
- cmap->red = BF.ColorMap[i+0*ncolors];
- cmap->green = BF.ColorMap[i+1*ncolors];
- cmap->blue = BF.ColorMap[i+2*ncolors];
- cmap++;
-
- /* Set the color table used for remapping */
- cregs[i*3+0] = BF.ColorMap[i+0*ncolors] << 16;
- cregs[i*3+1] = BF.ColorMap[i+1*ncolors] << 16;
- cregs[i*3+2] = BF.ColorMap[i+2*ncolors] << 16;
- }
- break;
- default:
- DB (KPrintF ("Unsupported Photometric Interpretation\n"));
- return FALSE;
- }
-
-
- DB (KPrintF ("getattrs\n"));
- bmhd->bmh_Depth=depth;
-
- /* Initialize the temporary bitmap */
-
- poolchip=CreatePool(MEMF_CLEAR|MEMF_CHIP,8192,8192);
- if(!poolchip) return FALSE;
-
- InitBitMap(&tbm, 8, (BF.ImageWidth +31)&~0x1f, BF.RowsPerStrip);
- if(!(tbm.Planes[0]=AllocPooled(poolchip,tbm.BytesPerRow*tbm.Rows*8)))
- {
- DB (KPrintF ("Unable to allocate temporary bitmap\n"));
- goto abort;
- }
- for(i=1;i<8;i++)
- tbm.Planes[i]=tbm.Planes[i-1]+tbm.BytesPerRow*tbm.Rows;
-
-
- /* allocate bitmap */
-
- if (bm = AllocBitMap (BF.ImageWidth, BF.ImageLength, depth, BMF_CLEAR, NULL))
- {
- InitRastPort (&rp);
- rp.BitMap = bm;
- DB (KPrintF ("Allocated bitmap\n"));
- }
- else
- {
- DB (KPrintF ("Unable to allocate bitmap\n"));
- goto abort;
- }
-
-
- buffer=AllocPooled(pool,BF.RowsPerStrip*tbm.BytesPerRow*8*BF.SamplesPerPixel);
- if(!buffer)
- {
- DB (KPrintF ("Unable to allocate buffer %ld\n",BF.RowsPerStrip*tbm.BytesPerRow*8*BF.SamplesPerPixel));
- goto abort;
- }
-
- DB (KPrintF ("Allocated buffer\n"));
-
- m=0;
- for(i=0;i<(BF.ImageLength + BF.RowsPerStrip - 1) / BF.RowsPerStrip;i++)
- {
- switch(BF.Compression)
- {
-
- case NO_COMPRESSION:
- Seek(fh,BF.StripOffsets[i],OFFSET_BEGINNING);
- if(Read(fh,buffer,BF.StripByteCounts[i])!=BF.StripByteCounts[i])
- {
- DB (KPrintF ("Unable to read strip %ld\n",i));
- goto abort;
- }
- break;
- case LZW:
-
- buffer3=AllocPooled(pool,BF.StripByteCounts[i]);
- if(!buffer3)
- {
- DB (KPrintF ("Unable to allocate buffer %ld\n",(long)BF.StripByteCounts[i]));
- goto abort;
- }
- Seek(fh,BF.StripOffsets[i],OFFSET_BEGINNING);
- if(Read(fh,buffer3,BF.StripByteCounts[i])!=BF.StripByteCounts[i])
- {
- DB (KPrintF ("Unable to read strip %ld\n",i));
- goto abort;
- }
- j=UnPackLZW(buffer3,buffer,BF.StripByteCounts[i],cb);
- DB (KPrintF ("Uncompressed %ld bytes\n",j));
- FreePooled(pool,buffer3,BF.StripByteCounts[i]);
- break;
- default:
- DB (KPrintF ("Unsupported Compression\n"));
- goto abort;
- }
-
- l=0;
- switch(BF.PhotometricInterpretation)
- {
- case BILEVEL_ZERO_IS_BLACK:
- case BILEVEL_ZERO_IS_WHITE:
- case COLOR_MAPPED_RGB:
- if(BF.BitsPerSample[0]==8)
- {
- DB (KPrintF ("strip %ld\r",i));
- Chunky2Planar(tbm.BytesPerRow*8*BF.RowsPerStrip,buffer,tbm.Planes[0]);
- DB (KPrintF ("c2p %ld\n",tbm.BytesPerRow*8*BF.RowsPerStrip));
- // WritePixelLine8(&rp,0,k+i*BF.RowsPerStrip,BF.ImageWidth,buffer2,&trp);
- if(BF.ImageWidth&0xf) /* image width is not a multiple of 16 */
- for(k=0;k<BF.RowsPerStrip&& k+i*BF.RowsPerStrip<BF.ImageLength;k++)
- BltBitMap(&tbm,k*BF.ImageWidth,0,bm,0,k+i*BF.RowsPerStrip,BF.ImageWidth,1,0xc0,0xff,NULL);
- else
- BltBitMap(&tbm,0,0,bm,0,i*BF.RowsPerStrip,BF.ImageWidth,BF.RowsPerStrip,0xc0,0xff,NULL);
- }
- if(BF.BitsPerSample[0]==1)
- for(k=0;k<BF.RowsPerStrip && k+i*BF.RowsPerStrip<BF.ImageLength;k++)
- {
- DB (KPrintF ("line %ld\r",k+i*BF.RowsPerStrip));
- memcpy(bm->Planes[0]+m,buffer+l,(BF.ImageWidth+7)/8);
- m+=bm->BytesPerRow;
- l+=(BF.ImageWidth+7)/8;
- }
- break;
- case TRUE_COLOR_RGB:
- {
- UBYTE r,g,b;
- int er,eg,eb,erred,ergreen,erblue,red,green,blue;
-
- ErrRed[0]=ErrGreen[0]=ErrBlue[0]=ErrRed[1]=ErrGreen[1]=ErrBlue[1]=0;
- if(BF.PlanarConfiguration==CHUNKY)
- {
- for(k=0;k<BF.RowsPerStrip && k+i*BF.RowsPerStrip<BF.ImageLength;k++)
- {
- erred=ErrRed[0];
- ergreen=ErrGreen[0];
- erblue=ErrBlue[0];
-
- DB (KPrintF ("line %ld\r",k+i*BF.RowsPerStrip));
- r=buffer[l++];
- g=buffer[l++];
- b=buffer[l++];
- buffer[k*BF.ImageWidth]= ( (((r+erred)/32)<<5) | (((g+ergreen)/32)<<2) | ((b+erblue)/64) );
- er=r & 0x1f;
- eg=g & 0x1f;
- eb=b & 0x3f;
-
- erred=ErrRed[1];
- ErrRed[0]=(er*5)>>4;
- ErrRed[1]=er>>4;
- erred+=(er*7)>>4;
-
- ergreen=ErrGreen[1];
- ErrGreen[0]=(eg*5)>>4;
- ErrGreen[1]=eg>>4;
- ergreen+=(eg*7)>>4;
-
- erblue=ErrBlue[1];
- ErrBlue[0]=(eb*5)>>4;
- ErrBlue[1]=eb>>4;
- erblue+=(eb*7)>>4;
-
- for(j=1;j<BF.ImageWidth;j++)
- {
-
- if(BF.Predictor==HORIZONTAL_DIFFERENCING)
- {
- red =((buffer[l]+r)&0xff)+erred;
- if(red>255) red=255;
- r+=buffer[l++];
- green=((buffer[l]+g)&0xff)+ergreen;
- if(green>255) green=255;
- g+=buffer[l++];
- blue=((buffer[l]+b)&0xff)+erblue;
- if(blue>255) blue=255;
- b+=buffer[l++];
- }
- else
- {
- red =buffer[l]+erred;
- if(red>255) red=255;
- r=buffer[l++];
- green=buffer[l]+ergreen;
- if(green>255) green=255;
- g=buffer[l++];
- blue=buffer[l]+erblue;
- if(blue>255) blue=255;
- b=buffer[l++];
- }
-
- buffer[k*BF.ImageWidth+j]= ( red & 0xe0) | ((green & 0xe0)>>3) | ((blue &0xc0)>>6);
- er=red & 0x1f;
- eg=green & 0x1f;
- eb=blue & 0x3f;
-
- erred=ErrRed[j+1];
- ErrRed[j-1]+=(er*3)>>4;
- ErrRed[j]+=(er*5)>>4;
- ErrRed[j+1]=er>>4;
- erred+=(er*7)>>4;
-
- ergreen=ErrGreen[j+1];
- ErrGreen[j-1]+=(eg*3)>>4;
- ErrGreen[j]+=(eg*5)>>4;
- ErrGreen[j+1]=eg>>4;
- ergreen+=(eg*7)>>4;
-
- erblue=ErrBlue[j+1];
- ErrBlue[j-1]+=(eb*3)>>4;
- ErrBlue[j]+=(eb*5)>>4;
- ErrBlue[j+1]=eb>>4;
- erblue+=(eb*7)>>4;
- }
- // WritePixelLine8(&rp,0,k+i*BF.RowsPerStrip,(BF.ImageWidth+15)&~7,buffer2,&trp);
- }
- Chunky2Planar(tbm.BytesPerRow*8*BF.RowsPerStrip,buffer,tbm.Planes[0]);
- // if(BF.ImageWidth&0x1f) /* image width is not a multiple of 32 */
- for(k=0;k<BF.RowsPerStrip&& k+i*BF.RowsPerStrip<BF.ImageLength;k++)
- BltBitMap(&tbm,(k*BF.ImageWidth)%(tbm.BytesPerRow*8),(k*BF.ImageWidth)/(tbm.BytesPerRow*8),bm,0,k+i*BF.RowsPerStrip,BF.ImageWidth,1,0xc0,0xff,NULL);
- // else
- // BltBitMap(&tbm,0,0,bm,0,i*BF.RowsPerStrip,BF.ImageWidth,BF.RowsPerStrip,0xc0,0xff,NULL);
- }
- if(BF.PlanarConfiguration==PLANAR) /* This is not implemented yet, since I couldn't find
- an image to test it */
- for(k=0;k<BF.RowsPerStrip && k+i*BF.RowsPerStrip<BF.ImageLength;k++)
- {
- DB (KPrintF ("line %ld\r",k+i*BF.RowsPerStrip));
- // memcpy(buffer2,buffer+l,BF.ImageWidth+16);
- // WritePixelLine8(&rp,0,k+i*BF.RowsPerStrip,BF.ImageWidth,buffer2,&trp);
- l+=BF.ImageWidth;
- }
- }
- break;
- default:
- DB (KPrintF ("Unsupported PhotometricInterpretation\n"));
- goto abort;
- }
- }
-
- setdtattrs (cb, o,
- DTA_NominalHoriz, BF.ImageWidth,
- DTA_NominalVert, BF.ImageLength,
- PDTA_BitMap, bm,
- PDTA_ModeID, modeid,
- TAG_DONE);
-
- DeletePool(poolchip);
- DB (KPrintF ("converted\n"));
- return TRUE;
-
- abort:
- DeletePool(poolchip);
- FreeBitMap (bm);
- SetIoErr (ERROR_NO_FREE_STORE);
- return FALSE;
-
- }/*************************** convert ************************/