home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / utilities / jpeg-dt35 / source / dispatcher.c < prev    next >
C/C++ Source or Header  |  2000-01-22  |  7KB  |  295 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/graphics_lib.h>
  6. #include <pragma/intuition_lib.h>
  7. #include <pragma/jpeg_lib.h>
  8. #include <pragma/utility_lib.h>
  9. #include <datatypes/pictureclass.h>
  10. #include <exec/memory.h>
  11. #include <intuition/icclass.h>
  12. #include <string.h>
  13. #include "class.h"
  14.  
  15. struct Arg1
  16. {
  17. long *dct,*scale,*quality,*smooth,gray,prog;
  18. };
  19.  
  20. ULONG SaveJPEG(IClass *cl,Object *obj,dtWrite *msg);
  21.  
  22. void ReadPrefs(Data *data)
  23. {
  24. char *var;
  25. data->dct=0;
  26. data->scale=1;
  27. data->quality=75;
  28. data->smooth=0;
  29. data->gray=0;
  30. data->prog=0;
  31. if(var=(char *)AllocVec(512,0))
  32.     {
  33.     if(GetVar("ENV:DataTypes/jpeg.prefs",var,512,LV_VAR|GVF_GLOBAL_ONLY)>=0)
  34.         {
  35.         RDArgs *rdargs;
  36.       if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
  37.             {
  38.             RDArgs *args;
  39.             Arg1 para;
  40.             rdargs->RDA_Source.CS_Buffer=var;
  41.             rdargs->RDA_Source.CS_Length=strlen(var);
  42.             rdargs->RDA_Source.CS_CurChr=0;
  43.             memset(¶,0,sizeof(Arg1));
  44.             if(args=ReadArgs("DCT/A/N,SCALE/A/N,QUALITY/A/N,SMOOTH/A/N,GRAY/S,PROGRESSIVE/S",(long *)¶,rdargs))
  45.                 {
  46.                 data->dct=*para.dct;
  47.                 if(data->dct<0) data->dct=0;
  48.                 else if(data->dct>2) data->dct=2;
  49.                 data->scale=*para.scale;
  50.                 if(data->scale<0) data->scale=0;
  51.                 else if(data->scale>3) data->scale=3;
  52.                 data->scale=1<<data->scale;
  53.                 data->quality=*para.quality;
  54.                 if(data->quality<1) data->quality=1;
  55.                 else if(data->quality>100) data->quality=100;
  56.                 data->smooth=*para.smooth;
  57.                 if(data->smooth<0) data->smooth=0;
  58.                 else if(data->smooth>100) data->smooth=100;
  59.                 data->gray=para.gray;
  60.                 data->prog=para.prog;
  61.                 FreeArgs(args);
  62.                 }
  63.             FreeDosObject(DOS_RDARGS,rdargs);
  64.             }
  65.         }
  66.     FreeVec(var);
  67.     }
  68. }
  69.  
  70. struct JPEGINFO
  71. {
  72. Object *obj;
  73. UBYTE *buffer;
  74. UWORD d,gray;
  75. };
  76.  
  77. static void _getline(UBYTE *scanline,ULONG y,ULONG numb,JPEGINFO *info)
  78. {
  79. if(info->gray) DoMethod(info->obj,PDTM_WRITEPIXELARRAY,scanline,PBPAFMT_GREY8,numb,0,y,numb,1);
  80. else
  81.     {
  82.     ULONG w=numb/3;
  83.     if(info->d>8) DoMethod(info->obj,PDTM_WRITEPIXELARRAY,scanline,PBPAFMT_RGB,numb,0,y,w,1);
  84.     else
  85.         {
  86.         register ULONG i;
  87.         register UBYTE *p1,*p2;
  88.         p1=info->buffer+w*y*4;
  89.         p2=scanline;
  90.         for(i=0;i<w;i++,p1+=4,p2+=3)
  91.             {
  92.             p1[1]=p2[0];
  93.             p1[2]=p2[1];
  94.             p1[3]=p2[2];
  95.             }
  96.         }
  97.     }
  98. }
  99.  
  100. static ULONG getline(register __a0 UBYTE *scanline,register __d0 ULONG line,register __d1 ULONG numb,register __a1 void *userdata)
  101. {
  102. _getline(scanline,line-1,numb,(JPEGINFO *)userdata);
  103. return 0;
  104. }
  105.  
  106. static void FillBMHD(Object *obj,BitMapHeader *bh,ULONG w,ULONG h,ULONG depth)
  107. {
  108. bh->bmh_Left=0;
  109. bh->bmh_Top=0;
  110. bh->bmh_Width=w;
  111. bh->bmh_Height=h;
  112. bh->bmh_PageWidth=w;
  113. bh->bmh_PageHeight=h;
  114. bh->bmh_Depth=depth;
  115. bh->bmh_Compression=cmpByteRun1;
  116. bh->bmh_XAspect=0;
  117. bh->bmh_YAspect=0;
  118. }
  119.  
  120. static ULONG GetBody_Gray(JPEGDecHandle *jph,BitMapHeader *bh,Object *obj,Data *data)
  121. {
  122. ULONG error=0;
  123. UBYTE *buffer;
  124. if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
  125.     {
  126.     if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
  127.         {
  128.         DoMethod(obj,PDTM_WRITEPIXELARRAY,buffer,PBPAFMT_GREY8,bh->bmh_Width,0,0,bh->bmh_Width,bh->bmh_Height);
  129.         }
  130.     else error=ERROR_NO_FREE_STORE;
  131.     FreeJPEGBuffer(buffer);
  132.     }
  133. else
  134.     {
  135.     JPEGINFO info={0,0,8,1};
  136.     if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
  137.     else error=ERROR_NO_FREE_STORE;
  138.     }
  139. return error;
  140. }
  141.  
  142. static ULONG GetBody_RGB(JPEGDecHandle *jph,BitMapHeader *bh,Object *obj,Data *data)
  143. {
  144. ULONG error=0;
  145. UBYTE *buffer;
  146. if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
  147.     {
  148.     if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
  149.         DoMethod(obj,PDTM_WRITEPIXELARRAY,buffer,PBPAFMT_RGB,bh->bmh_Width*3,0,0,bh->bmh_Width,bh->bmh_Height);
  150.     else error=ERROR_NO_FREE_STORE;
  151.     FreeJPEGBuffer(buffer);
  152.     }
  153. else
  154.     {
  155.     JPEGINFO info={obj,0,24,0};
  156.     if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
  157.     }
  158. return error;
  159. }
  160.  
  161. static ULONG GetPicture(IClass *cl,Object *obj)
  162. {
  163. ULONG error=0;
  164. long err;
  165. BPTR file;
  166. BitMapHeader *bh;
  167. GetDTAttrs(obj,DTA_Name,&bh,TAG_END);
  168. if(bh) SetDTAttrs(obj,0,0,DTA_ObjName,bh,TAG_END);
  169. GetDTAttrs(obj,DTA_Handle,&file,PDTA_BitMapHeader,&bh,TAG_END);
  170. if(bh)
  171.     {
  172.     JPEGDecHandle *jph;
  173.     if(!file)
  174.         {
  175.         GetDTAttrs(obj,DTA_SourceType,&err,TAG_END);
  176.         if(err!=DTST_RAM) return ERROR_REQUIRED_ARG_MISSING;
  177.         else return 0;
  178.         }
  179.     if(!AllocJPEGDecompress(&jph,JPG_SrcFile,file,TAG_END))
  180.         {
  181.         UBYTE colorspace;
  182.         ULONG w,h,bpp;
  183.         Data *data=(Data *)INST_DATA(cl,obj);
  184.         ReadPrefs(data);
  185.         if(!GetJPEGInfo(jph,JPG_Width,&w,JPG_Height,&h,JPG_ColourSpace,&colorspace,JPG_BytesPerPixel,&bpp,JPG_ScaleDenom,data->scale,TAG_END))
  186.             {
  187.             bh->bmh_Left=0;
  188.             bh->bmh_Top=0;
  189.             bh->bmh_Width=w;
  190.             bh->bmh_Height=h;
  191.             bh->bmh_PageWidth=w;
  192.             bh->bmh_PageHeight=h;
  193.             bh->bmh_Depth=(colorspace==JPCS_RGB)?24:8;
  194.             bh->bmh_Compression=cmpByteRun1;
  195.             bh->bmh_XAspect=0;
  196.             bh->bmh_YAspect=0;
  197.             SetDTAttrs(obj,0,0,DTA_ErrorNumber,&error,DTA_NominalHoriz,w,DTA_NominalVert,h,PDTA_SourceMode,PMODE_V43,PDTA_ModeID,0,TAG_END);
  198.             if(!error)
  199.                 {
  200.                 switch(colorspace)
  201.                     {
  202.                     case JPCS_GRAYSCALE:
  203.                         error=GetBody_Gray(jph,bh,obj,data);
  204.                         break;
  205.                     case JPCS_RGB:
  206.                         error=GetBody_RGB(jph,bh,obj,data);
  207.                         break;
  208.                     default:
  209.                         error=ERROR_NOT_IMPLEMENTED;
  210.                     }
  211.                 }
  212.             }
  213.         else error=DTERROR_INVALID_DATA;
  214.         }
  215.     else error=DTERROR_INVALID_DATA;
  216.     }
  217. else error=ERROR_NO_FREE_STORE;
  218. return error;
  219. }
  220.  
  221. static ULONG mNew(IClass *cl,Object *obj,opSet *msg)
  222. {
  223. TagItem *ti;
  224. if(ti=FindTagItem(DTA_SourceType,(((opSet *)msg)->ops_AttrList)))
  225.     {
  226.     if(ti->ti_Data!=DTST_FILE&&ti->ti_Data!=DTST_CLIPBOARD&&ti->ti_Data!=DTST_RAM)
  227.         {
  228.         SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  229.         return 0;
  230.         }
  231.     }
  232. if(obj==(Object *)cl)
  233.     {
  234.     if(obj=(Object *)DoSuperMethodA(cl,obj,Msg(msg)))
  235.         {
  236.         ULONG error;
  237.         if(error=GetPicture(cl,obj))
  238.             {
  239.             SetIoErr(error);
  240.             CoerceMethod(cl,obj,OM_DISPOSE);
  241.             obj=0;
  242.             }
  243.         }
  244.     }
  245. else
  246.     {
  247.     SetIoErr(ERROR_NOT_IMPLEMENTED);
  248.     obj=0;
  249.     }
  250. return ULONG(obj);
  251. }
  252.  
  253. static ULONG mSet(IClass *cl,Object *obj,opSet *msg)
  254. {
  255. ULONG retval;
  256. if(retval=DoSuperMethodA(cl,obj,Msg(msg)))
  257.     {
  258.     RastPort *rp;
  259.     if(rp=ObtainGIRPort(msg->ops_GInfo))
  260.         {
  261.         DoMethod(obj,GM_RENDER,msg->ops_GInfo,rp,GREDRAW_UPDATE);
  262.         ReleaseGIRPort(rp);
  263.         retval=0;
  264.         }
  265.     }
  266. return retval;
  267. }
  268.  
  269. static ULONG mWrite(IClass *cl,Object *obj,dtWrite *msg)
  270. {
  271. return (msg->dtw_Mode==DTWM_IFF)?DoSuperMethodA(cl,obj,Msg(msg)):SaveJPEG(cl,obj,msg);
  272. }
  273.  
  274. extern "C" ULONG Dispatcher(register __a0 IClass *cl,register __a2 Object *obj,register __a1 Msg msg)
  275. {
  276. ULONG retval;
  277. switch(msg->MethodID)
  278.     {
  279.     case OM_NEW:
  280.         retval=mNew(cl,obj,(opSet *)msg);
  281.         break;
  282.     case OM_UPDATE:
  283.         if(DoMethod(obj,ICM_CHECKLOOP)) break;
  284.     case OM_SET:
  285.         retval=mSet(cl,obj,(opSet *)msg);
  286.         break;
  287.     case DTM_WRITE:
  288.         retval=mWrite(cl,obj,(dtWrite *)msg);
  289.         break;
  290.     default:
  291.         retval=DoSuperMethodA(cl,obj,msg);
  292.         }
  293. return retval;
  294. }
  295.