home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / utilities / pcd-dt / source / dispatcher.c next >
Encoding:
C/C++ Source or Header  |  2000-01-22  |  8.5 KB  |  371 lines

  1. #include <clib/alib_protos.h>
  2. #include <pragma/datatypes_lib.h>
  3. #include <pragma/dos_lib.h>
  4. #include <pragma/exec_lib.h>
  5. #include <pragma/intuition_lib.h>
  6. #include <pragma/graphics_lib.h>
  7. #include <pragma/render_lib.h>
  8. #include <pragma/utility_lib.h>
  9. #include <cybergraphx/cybergraphics.h>
  10. #include <datatypes/pictureclass.h>
  11. #include <dos/dostags.h>
  12. #include <exec/memory.h>
  13. #include <intuition/icclass.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16.  
  17. struct Arg1
  18. {
  19. long *mode,*res,*dither,*depth;
  20. };
  21.  
  22. struct Arg2
  23. {
  24. long mode,res,dither,depth;
  25. };
  26.  
  27. extern Library *SuperClassBase;
  28.  
  29. static void ReadPrefs(Arg2 *arg)
  30. {
  31. char *var;
  32. arg->mode=1;
  33. arg->res=2;
  34. arg->dither=0;
  35. arg->depth=8;
  36. if(var=(char *)AllocVec(256,0))
  37.     {
  38.     if(GetVar("ENV:DataTypes/pcd.prefs",var,256,LV_VAR|GVF_GLOBAL_ONLY)>=0)
  39.         {
  40.         RDArgs *rdargs;
  41.       if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
  42.             {
  43.             RDArgs *args;
  44.             Arg1 para={0,0,0,0};
  45.             rdargs->RDA_Source.CS_Buffer=var;
  46.             rdargs->RDA_Source.CS_Length=strlen(var);
  47.             rdargs->RDA_Source.CS_CurChr=0;
  48.             if(args=ReadArgs("MODE/A/N,RESOLUTION/A/N,DITHER/A/N,DEPTH/A/N",(long *)¶,rdargs))
  49.                 {
  50.                 if(para.mode)
  51.                     {
  52.                     arg->mode=*para.mode;
  53.                     if(arg->mode<0) arg->mode=0;
  54.                     else if(arg->mode>1) arg->mode=1;
  55.                     }
  56.                 if(para.res)
  57.                     {
  58.                     arg->res=*para.res;
  59.                     if(arg->res<0) arg->res=0;
  60.                     else if(arg->res>5) arg->res=5;
  61.                     }
  62.                 if(para.dither)
  63.                     {
  64.                     arg->dither=*para.dither;
  65.                     if(arg->dither<0) arg->dither=0;
  66.                     else if(arg->dither>1) arg->dither=1;
  67.                     }
  68.                 if(para.depth)
  69.                     {
  70.                     arg->depth=*para.depth;
  71.                     if(arg->depth<3) arg->depth=3;
  72.                     else if(arg->depth>8) arg->depth=8;
  73.                     }
  74.                 FreeArgs(args);
  75.                 }
  76.             FreeDosObject(DOS_RDARGS,rdargs);
  77.             }
  78.         }
  79.     FreeVec(var);
  80.     }
  81. if(SuperClassBase->lib_Version<43) arg->mode=0;
  82. }
  83.  
  84. ULONG Colors2DT(Object *obj,UBYTE *color)
  85. {
  86. UBYTE *cr;
  87. ULONG *cregs,i,num,error=0;
  88. GetDTAttrs(obj,PDTA_NumColors,&num,PDTA_ColorRegisters,&cr,PDTA_CRegs,&cregs,TAG_END);
  89. if(cr&&cregs)
  90.     {
  91.     for(i=0;i<num;i++,cr+=3,cregs+=3,color+=4)
  92.         {
  93.         cr[0]=color[1];
  94.         cr[1]=color[2];
  95.         cr[2]=color[3];
  96.         cregs[0]=cr[0]<<24;
  97.         cregs[1]=cr[1]<<24;
  98.         cregs[2]=cr[2]<<24;
  99.         }
  100.     }
  101. else error=ERROR_NO_FREE_STORE;
  102. return error;
  103. }
  104.  
  105. static ULONG ReadP6(Object *obj,BitMapHeader *bh,BitMap *bm,BPTR file,Arg2 *arg)
  106. {
  107. ULONG error=0;
  108. UBYTE *rgb;
  109. if(rgb=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height*4,MEMF_CLEAR))
  110.     {
  111.     UBYTE *buffer;
  112.     if(buffer=(UBYTE *)AllocVec(bh->bmh_Width*3,0))
  113.         {
  114.         UWORD y;
  115.         UBYTE *p1=rgb;
  116.         for(y=0;y<bh->bmh_Height;y++)
  117.             {
  118.             UWORD x;
  119.             UBYTE *p2=buffer;
  120.             if(Read(file,buffer,bh->bmh_Width*3)!=bh->bmh_Width*3)
  121.                 {
  122.                 error=DTERROR_NOT_ENOUGH_DATA;
  123.                 break;
  124.                 }
  125.             for(x=0;x<bh->bmh_Width;x++,p1+=4,p2+=3)
  126.                 {
  127.                 p1[1]=p2[0];
  128.                 p1[2]=p2[1];
  129.                 p1[3]=p2[2];
  130.                 }
  131.             }
  132.         FreeVec(buffer);
  133.         if(!error)
  134.             {
  135.             APTR rmh;
  136.             if(rmh=CreateRMHandler(RND_MemType,RMHTYPE_POOL,TAG_END))
  137.                 {
  138.                 ULONG *palette;
  139.                 if(palette=CreatePalette(RND_RMHandler,rmh,TAG_END))
  140.                     {
  141.                     APTR hst;
  142.                     if(hst=CreateHistogram(RND_RMHandler,rmh,TAG_END))
  143.                         {
  144.                         if(AddRGBImage(hst,(ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,TAG_END)==ADDH_SUCCESS)
  145.                             {
  146.                             if(ExtractPalette(hst,palette,1<<bh->bmh_Depth,TAG_END)==EXTP_SUCCESS)
  147.                                 {
  148.                                 UBYTE *chunky;
  149.                                 if(chunky=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height,0))
  150.                                     {
  151.                                     if(Render((ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,chunky,palette,RND_DitherMode,arg->dither,TAG_END)==REND_SUCCESS)
  152.                                         {
  153.                                         UBYTE *color;
  154.                                         if(color=(UBYTE *)AllocVec((1<<bh->bmh_Depth)*4,0))
  155.                                             {
  156.                                             ExportPalette(palette,color,TAG_END);
  157.                                             if(!(error=Colors2DT(obj,color))) Chunky2BitMap(chunky,0,0,bh->bmh_Width,bh->bmh_Height,bm,0,0,TAG_END);
  158.                                             FreeVec(color);
  159.                                             }
  160.                                         else error=ERROR_NO_FREE_STORE;
  161.                                         }
  162.                                     else error=ERROR_NO_FREE_STORE;
  163.                                     FreeVec(chunky);
  164.                                     }
  165.                                 else error=ERROR_NO_FREE_STORE;
  166.                                 }
  167.                             else error=ERROR_NO_FREE_STORE;
  168.                             }
  169.                         else error=ERROR_NO_FREE_STORE;
  170.                         DeleteHistogram(hst);
  171.                         }
  172.                     else error=ERROR_NO_FREE_STORE;
  173.                     DeletePalette(palette);
  174.                     }
  175.                 else error=ERROR_NO_FREE_STORE;
  176.                 DeleteRMHandler(rmh);
  177.                 }
  178.             else error=ERROR_NO_FREE_STORE;
  179.             }
  180.         }
  181.     else error=ERROR_NO_FREE_STORE;
  182.     FreeVec(rgb);
  183.     }
  184. else error=ERROR_NO_FREE_STORE;
  185. return error;
  186. }
  187.  
  188. static ULONG ReadP6_V43(Object *obj,BitMapHeader *bh,BPTR file)
  189. {
  190. ULONG error=0,len=bh->bmh_Width*bh->bmh_Height*3;
  191. UBYTE *pix;
  192. if(pix=(UBYTE *)AllocVec(len,0))
  193.     {
  194.     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);
  195.     else error=DTERROR_NOT_ENOUGH_DATA;
  196.     FreeVec(pix);
  197.     }
  198. else if(pix=(UBYTE *)AllocVec(bh->bmh_Width*3,0))
  199.     {
  200.     UWORD y;
  201.     for(y=0;y<bh->bmh_Height;y++)
  202.         {
  203.         if(Read(file,pix,bh->bmh_Width*3)!=bh->bmh_Width*3)
  204.             {
  205.             error=DTERROR_NOT_ENOUGH_DATA;
  206.             break;
  207.             }
  208.         DoMethod(obj,PDTM_WRITEPIXELARRAY,pix,RECTFMT_RGB,bh->bmh_Width*3,0,y,bh->bmh_Width,1);
  209.         }
  210.     FreeVec(pix);
  211.     }
  212. else error=ERROR_NO_FREE_STORE;
  213. return error;
  214. }
  215.  
  216. static ULONG ReadNum(BPTR file)
  217. {
  218. ULONG retval=0;
  219. for(;;)
  220.     {
  221.     char c;
  222.     if(Read(file,&c,1)!=1) return 0;
  223.     if(c==10||c==32) break;
  224.     retval*=10;
  225.     retval+=c-'0';
  226.     }
  227. return retval;
  228. }
  229.  
  230. static ULONG GetPicture(IClass *cl,Object *obj)
  231. {
  232. ULONG error=0;
  233. BPTR nil;
  234. if(nil=Open("NIL:",MODE_OLDFILE))
  235.     {
  236.     char *fname,*dname,tmp[L_tmpnam];
  237.     Arg2 arg;
  238.     ReadPrefs(&arg);
  239.     GetDTAttrs(obj,DTA_Name,&dname,TAG_END);
  240.     if(dname)
  241.         {
  242.         SetDTAttrs(obj,0,0,DTA_ObjName,dname,TAG_END);
  243.         tmpnam(tmp);
  244.         strncpy(tmp,"PIPE:",5);
  245.         if(fname=(char *)AllocVec(strlen(dname)+L_tmpnam+50,0))
  246.             {
  247.             SPrintf(fname,"run pcdtoppm >%s -%lu -ppm \"%s%\"",tmp,arg.res+1,dname);
  248.             if(Execute(fname,nil,nil)!=DOSFALSE)
  249.                 {
  250.                 BPTR file;
  251.                 if(file=Open(tmp,MODE_OLDFILE))
  252.                     {
  253.                     BitMapHeader *bh;
  254.                     char head[3];
  255.                     GetDTAttrs(obj,PDTA_BitMapHeader,&bh,TAG_END);
  256.                     if(bh)
  257.                         {
  258.                         if(Read(file,head,3)==3)
  259.                             {
  260.                             bh->bmh_Width=ReadNum(file);
  261.                             bh->bmh_PageWidth=bh->bmh_Width;
  262.                             bh->bmh_Height=ReadNum(file);
  263.                             bh->bmh_PageHeight=bh->bmh_Height;
  264.                             bh->bmh_Compression=1;
  265.                             ReadNum(file);
  266.                             if(!arg.mode)
  267.                                 {
  268.                                 BitMap *bm;
  269.                                 bh->bmh_Depth=arg.depth;
  270.                                 SetDTAttrs(obj,0,0,DTA_NominalHoriz,bh->bmh_Width,DTA_NominalVert,bh->bmh_Height,PDTA_NumColors,1<<arg.depth,TAG_END);
  271.                                 if(bm=AllocBitMap(bh->bmh_Width,bh->bmh_Height,bh->bmh_Depth,BMF_CLEAR|BMF_STANDARD|BMF_DISPLAYABLE,0))
  272.                                     {
  273.                                     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);
  274.                                     error=ReadP6(obj,bh,bm,file,&arg);
  275.                                     }
  276.                                 else error=ERROR_NO_FREE_STORE;
  277.                                 }
  278.                             else
  279.                                 {
  280.                                 bh->bmh_Depth=24;
  281.                                 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);
  282.                                 if(!error) error=ReadP6_V43(obj,bh,file);
  283.                                 }
  284.                             }
  285.                         else error=DTERROR_NOT_ENOUGH_DATA;
  286.                         }
  287.                     else error=ERROR_NO_FREE_STORE;
  288.                     Close(file);
  289.                     }
  290.                 else error=IoErr();
  291.                 }
  292.             else error=IoErr();
  293.             FreeVec(fname);
  294.             }
  295.         else error=ERROR_NO_FREE_STORE;
  296.         }
  297.     else error=ERROR_NO_FREE_STORE;
  298.     Close(nil);
  299.     }
  300. else error=IoErr();
  301. return error;
  302. }
  303.  
  304. static ULONG mNew(IClass *cl,Object *obj,opSet *msg)
  305. {
  306. TagItem *ti;
  307. if(ti=FindTagItem(DTA_SourceType,msg->ops_AttrList))
  308.     {
  309.     if(ti->ti_Data!=DTST_FILE&&ti->ti_Data!=DTST_CLIPBOARD&&ti->ti_Data!=DTST_RAM)
  310.         {
  311.         SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  312.         return 0;
  313.         }
  314.     }
  315. if(obj==(Object *)cl)
  316.     {
  317.     if(obj=(Object *)DoSuperMethodA(cl,obj,Msg(msg)))
  318.         {
  319.         ULONG error;
  320.         if(error=GetPicture(cl,obj))
  321.             {
  322.             SetIoErr(error);
  323.             CoerceMethod(cl,obj,OM_DISPOSE);
  324.             obj=0;
  325.             }
  326.         }
  327.     }
  328. else
  329.     {
  330.     SetIoErr(ERROR_NOT_IMPLEMENTED);
  331.     obj=0;
  332.     }
  333. return ULONG(obj);
  334. }
  335.  
  336. static ULONG mSet(IClass *cl,Object *obj,opSet *msg)
  337. {
  338. ULONG retval;
  339. if(retval=DoSuperMethodA(cl,obj,Msg(msg)))
  340.     {
  341.     RastPort *rp;
  342.     if(rp=ObtainGIRPort(msg->ops_GInfo))
  343.         {
  344.         DoMethod(obj,GM_RENDER,msg->ops_GInfo,rp,GREDRAW_UPDATE);
  345.         ReleaseGIRPort(rp);
  346.         retval=0;
  347.         }
  348.     }
  349. return retval;
  350. }
  351.  
  352. extern "C" ULONG Dispatcher(register __a0 IClass *cl,register __a2 Object *obj,register __a1 Msg msg)
  353. {
  354. ULONG retval;
  355. switch(msg->MethodID)
  356.     {
  357.     case OM_NEW:
  358.         retval=mNew(cl,obj,(opSet *)msg);
  359.         break;
  360.     case OM_UPDATE:
  361.         if(DoMethod(obj,ICM_CHECKLOOP)) break;
  362.     case OM_SET:
  363.         retval=mSet(cl,obj,(opSet *)msg);
  364.         break;
  365.     default:
  366.         retval=DoSuperMethodA(cl,obj,msg);
  367.         }
  368. return retval;
  369. }
  370.  
  371.