home *** CD-ROM | disk | FTP | other *** search
- #include <clib/alib_protos.h>
- #include <pragma/datatypes_lib.h>
- #include <pragma/dos_lib.h>
- #include <pragma/exec_lib.h>
- #include <pragma/intuition_lib.h>
- #include <pragma/graphics_lib.h>
- #include <pragma/render_lib.h>
- #include <pragma/utility_lib.h>
- #include <cybergraphx/cybergraphics.h>
- #include <datatypes/pictureclass.h>
- #include <dos/dostags.h>
- #include <exec/memory.h>
- #include <intuition/icclass.h>
- #include <stdio.h>
- #include <string.h>
-
- struct Arg1
- {
- long *mode,*res,*dither,*depth;
- };
-
- struct Arg2
- {
- long mode,res,dither,depth;
- };
-
- extern Library *SuperClassBase;
-
- static void ReadPrefs(Arg2 *arg)
- {
- char *var;
- arg->mode=1;
- arg->res=2;
- arg->dither=0;
- arg->depth=8;
- if(var=(char *)AllocVec(256,0))
- {
- if(GetVar("ENV:DataTypes/pcd.prefs",var,256,LV_VAR|GVF_GLOBAL_ONLY)>=0)
- {
- RDArgs *rdargs;
- if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
- {
- RDArgs *args;
- Arg1 para={0,0,0,0};
- rdargs->RDA_Source.CS_Buffer=var;
- rdargs->RDA_Source.CS_Length=strlen(var);
- rdargs->RDA_Source.CS_CurChr=0;
- if(args=ReadArgs("MODE/A/N,RESOLUTION/A/N,DITHER/A/N,DEPTH/A/N",(long *)¶,rdargs))
- {
- if(para.mode)
- {
- arg->mode=*para.mode;
- if(arg->mode<0) arg->mode=0;
- else if(arg->mode>1) arg->mode=1;
- }
- if(para.res)
- {
- arg->res=*para.res;
- if(arg->res<0) arg->res=0;
- else if(arg->res>5) arg->res=5;
- }
- if(para.dither)
- {
- arg->dither=*para.dither;
- if(arg->dither<0) arg->dither=0;
- else if(arg->dither>1) arg->dither=1;
- }
- if(para.depth)
- {
- arg->depth=*para.depth;
- if(arg->depth<3) arg->depth=3;
- else if(arg->depth>8) arg->depth=8;
- }
- FreeArgs(args);
- }
- FreeDosObject(DOS_RDARGS,rdargs);
- }
- }
- FreeVec(var);
- }
- if(SuperClassBase->lib_Version<43) arg->mode=0;
- }
-
- ULONG Colors2DT(Object *obj,UBYTE *color)
- {
- UBYTE *cr;
- ULONG *cregs,i,num,error=0;
- GetDTAttrs(obj,PDTA_NumColors,&num,PDTA_ColorRegisters,&cr,PDTA_CRegs,&cregs,TAG_END);
- if(cr&&cregs)
- {
- for(i=0;i<num;i++,cr+=3,cregs+=3,color+=4)
- {
- cr[0]=color[1];
- cr[1]=color[2];
- cr[2]=color[3];
- cregs[0]=cr[0]<<24;
- cregs[1]=cr[1]<<24;
- cregs[2]=cr[2]<<24;
- }
- }
- else error=ERROR_NO_FREE_STORE;
- return error;
- }
-
- static ULONG ReadP6(Object *obj,BitMapHeader *bh,BitMap *bm,BPTR file,Arg2 *arg)
- {
- ULONG error=0;
- UBYTE *rgb;
- if(rgb=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height*4,MEMF_CLEAR))
- {
- UBYTE *buffer;
- if(buffer=(UBYTE *)AllocVec(bh->bmh_Width*3,0))
- {
- UWORD y;
- UBYTE *p1=rgb;
- for(y=0;y<bh->bmh_Height;y++)
- {
- UWORD x;
- UBYTE *p2=buffer;
- if(Read(file,buffer,bh->bmh_Width*3)!=bh->bmh_Width*3)
- {
- error=DTERROR_NOT_ENOUGH_DATA;
- break;
- }
- for(x=0;x<bh->bmh_Width;x++,p1+=4,p2+=3)
- {
- p1[1]=p2[0];
- p1[2]=p2[1];
- p1[3]=p2[2];
- }
- }
- FreeVec(buffer);
- if(!error)
- {
- APTR rmh;
- if(rmh=CreateRMHandler(RND_MemType,RMHTYPE_POOL,TAG_END))
- {
- ULONG *palette;
- if(palette=CreatePalette(RND_RMHandler,rmh,TAG_END))
- {
- APTR hst;
- if(hst=CreateHistogram(RND_RMHandler,rmh,TAG_END))
- {
- if(AddRGBImage(hst,(ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,TAG_END)==ADDH_SUCCESS)
- {
- if(ExtractPalette(hst,palette,1<<bh->bmh_Depth,TAG_END)==EXTP_SUCCESS)
- {
- UBYTE *chunky;
- if(chunky=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height,0))
- {
- if(Render((ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,chunky,palette,RND_DitherMode,arg->dither,TAG_END)==REND_SUCCESS)
- {
- UBYTE *color;
- if(color=(UBYTE *)AllocVec((1<<bh->bmh_Depth)*4,0))
- {
- ExportPalette(palette,color,TAG_END);
- if(!(error=Colors2DT(obj,color))) Chunky2BitMap(chunky,0,0,bh->bmh_Width,bh->bmh_Height,bm,0,0,TAG_END);
- FreeVec(color);
- }
- else error=ERROR_NO_FREE_STORE;
- }
- else error=ERROR_NO_FREE_STORE;
- FreeVec(chunky);
- }
- else error=ERROR_NO_FREE_STORE;
- }
- else error=ERROR_NO_FREE_STORE;
- }
- else error=ERROR_NO_FREE_STORE;
- DeleteHistogram(hst);
- }
- else error=ERROR_NO_FREE_STORE;
- DeletePalette(palette);
- }
- else error=ERROR_NO_FREE_STORE;
- DeleteRMHandler(rmh);
- }
- else error=ERROR_NO_FREE_STORE;
- }
- }
- else error=ERROR_NO_FREE_STORE;
- FreeVec(rgb);
- }
- else error=ERROR_NO_FREE_STORE;
- return error;
- }
-
- static ULONG ReadP6_V43(Object *obj,BitMapHeader *bh,BPTR file)
- {
- ULONG error=0,len=bh->bmh_Width*bh->bmh_Height*3;
- UBYTE *pix;
- if(pix=(UBYTE *)AllocVec(len,0))
- {
- if(Read(file,pix,len)==len) DoMethod(obj,PDTM_WRITEPIXELARRAY,pix,RECTFMT_RGB,bh->bmh_Width*3,0,0,bh->bmh_Width,bh->bmh_Height);
- else error=DTERROR_NOT_ENOUGH_DATA;
- FreeVec(pix);
- }
- else if(pix=(UBYTE *)AllocVec(bh->bmh_Width*3,0))
- {
- UWORD y;
- for(y=0;y<bh->bmh_Height;y++)
- {
- if(Read(file,pix,bh->bmh_Width*3)!=bh->bmh_Width*3)
- {
- error=DTERROR_NOT_ENOUGH_DATA;
- break;
- }
- DoMethod(obj,PDTM_WRITEPIXELARRAY,pix,RECTFMT_RGB,bh->bmh_Width*3,0,y,bh->bmh_Width,1);
- }
- FreeVec(pix);
- }
- else error=ERROR_NO_FREE_STORE;
- return error;
- }
-
- static ULONG ReadNum(BPTR file)
- {
- ULONG retval=0;
- for(;;)
- {
- char c;
- if(Read(file,&c,1)!=1) return 0;
- if(c==10||c==32) break;
- retval*=10;
- retval+=c-'0';
- }
- return retval;
- }
-
- static ULONG GetPicture(IClass *cl,Object *obj)
- {
- ULONG error=0;
- BPTR nil;
- if(nil=Open("NIL:",MODE_OLDFILE))
- {
- char *fname,*dname,tmp[L_tmpnam];
- Arg2 arg;
- ReadPrefs(&arg);
- GetDTAttrs(obj,DTA_Name,&dname,TAG_END);
- if(dname)
- {
- SetDTAttrs(obj,0,0,DTA_ObjName,dname,TAG_END);
- tmpnam(tmp);
- strncpy(tmp,"PIPE:",5);
- if(fname=(char *)AllocVec(strlen(dname)+L_tmpnam+50,0))
- {
- SPrintf(fname,"run pcdtoppm >%s -%lu -ppm \"%s%\"",tmp,arg.res+1,dname);
- if(Execute(fname,nil,nil)!=DOSFALSE)
- {
- BPTR file;
- if(file=Open(tmp,MODE_OLDFILE))
- {
- BitMapHeader *bh;
- char head[3];
- GetDTAttrs(obj,PDTA_BitMapHeader,&bh,TAG_END);
- if(bh)
- {
- if(Read(file,head,3)==3)
- {
- bh->bmh_Width=ReadNum(file);
- bh->bmh_PageWidth=bh->bmh_Width;
- bh->bmh_Height=ReadNum(file);
- bh->bmh_PageHeight=bh->bmh_Height;
- bh->bmh_Compression=1;
- ReadNum(file);
- if(!arg.mode)
- {
- BitMap *bm;
- bh->bmh_Depth=arg.depth;
- SetDTAttrs(obj,0,0,DTA_NominalHoriz,bh->bmh_Width,DTA_NominalVert,bh->bmh_Height,PDTA_NumColors,1<<arg.depth,TAG_END);
- if(bm=AllocBitMap(bh->bmh_Width,bh->bmh_Height,bh->bmh_Depth,BMF_CLEAR|BMF_STANDARD|BMF_DISPLAYABLE,0))
- {
- SetDTAttrs(obj,0,0,PDTA_ModeID,BestModeID(BIDTAG_NominalWidth,bh->bmh_Width,BIDTAG_NominalHeight,bh->bmh_Height,BIDTAG_Depth,bh->bmh_Depth,TAG_END),PDTA_BitMap,bm,TAG_END);
- error=ReadP6(obj,bh,bm,file,&arg);
- }
- else error=ERROR_NO_FREE_STORE;
- }
- else
- {
- bh->bmh_Depth=24;
- SetDTAttrs(obj,0,0,DTA_ErrorNumber,&error,DTA_NominalHoriz,bh->bmh_Width,DTA_NominalVert,bh->bmh_Height,PDTA_ModeID,0,PDTA_SourceMode,PMODE_V43,TAG_END);
- if(!error) error=ReadP6_V43(obj,bh,file);
- }
- }
- else error=DTERROR_NOT_ENOUGH_DATA;
- }
- else error=ERROR_NO_FREE_STORE;
- Close(file);
- }
- else error=IoErr();
- }
- else error=IoErr();
- FreeVec(fname);
- }
- else error=ERROR_NO_FREE_STORE;
- }
- else error=ERROR_NO_FREE_STORE;
- Close(nil);
- }
- else error=IoErr();
- return error;
- }
-
- static ULONG mNew(IClass *cl,Object *obj,opSet *msg)
- {
- TagItem *ti;
- if(ti=FindTagItem(DTA_SourceType,msg->ops_AttrList))
- {
- if(ti->ti_Data!=DTST_FILE&&ti->ti_Data!=DTST_CLIPBOARD&&ti->ti_Data!=DTST_RAM)
- {
- SetIoErr(ERROR_OBJECT_WRONG_TYPE);
- return 0;
- }
- }
- if(obj==(Object *)cl)
- {
- if(obj=(Object *)DoSuperMethodA(cl,obj,Msg(msg)))
- {
- ULONG error;
- if(error=GetPicture(cl,obj))
- {
- SetIoErr(error);
- CoerceMethod(cl,obj,OM_DISPOSE);
- obj=0;
- }
- }
- }
- else
- {
- SetIoErr(ERROR_NOT_IMPLEMENTED);
- obj=0;
- }
- return ULONG(obj);
- }
-
- static ULONG mSet(IClass *cl,Object *obj,opSet *msg)
- {
- ULONG retval;
- if(retval=DoSuperMethodA(cl,obj,Msg(msg)))
- {
- RastPort *rp;
- if(rp=ObtainGIRPort(msg->ops_GInfo))
- {
- DoMethod(obj,GM_RENDER,msg->ops_GInfo,rp,GREDRAW_UPDATE);
- ReleaseGIRPort(rp);
- retval=0;
- }
- }
- return retval;
- }
-
- extern "C" ULONG Dispatcher(register __a0 IClass *cl,register __a2 Object *obj,register __a1 Msg msg)
- {
- ULONG retval;
- switch(msg->MethodID)
- {
- case OM_NEW:
- retval=mNew(cl,obj,(opSet *)msg);
- break;
- case OM_UPDATE:
- if(DoMethod(obj,ICM_CHECKLOOP)) break;
- case OM_SET:
- retval=mSet(cl,obj,(opSet *)msg);
- break;
- default:
- retval=DoSuperMethodA(cl,obj,msg);
- }
- return retval;
- }
-
-