home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / utilities / jpeg-dt / source / dispatcher.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-22  |  11.2 KB  |  455 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/render_lib.h>
  9. #include <pragma/utility_lib.h>
  10. #include <render/renderhooks.h>
  11. #include <cybergraphx/cybergraphics.h>
  12. #include <datatypes/pictureclass.h>
  13. #include <exec/memory.h>
  14. #include <intuition/icclass.h>
  15. #include <string.h>
  16. #include "class.h"
  17.  
  18. struct Arg1
  19. {
  20. long *mode,*dither,*depth,*dct,*scale,*quality,*smooth,gray,prog;
  21. };
  22.  
  23. ULONG SaveJPEG(IClass *cl,Object *obj,dtWrite *msg);
  24.  
  25. extern Library *SuperClassBase;
  26.  
  27. void ReadPrefs(Data *data)
  28. {
  29. char *var;
  30. data->mode=1;
  31. data->dither=0;
  32. data->depth=8;
  33. data->dct=0;
  34. data->scale=1;
  35. data->quality=75;
  36. data->smooth=0;
  37. data->gray=0;
  38. data->prog=0;
  39. if(var=(char *)AllocVec(512,0))
  40.     {
  41.     if(GetVar("ENV:DataTypes/jpeg.prefs",var,512,LV_VAR|GVF_GLOBAL_ONLY)>=0)
  42.         {
  43.         RDArgs *rdargs;
  44.       if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
  45.             {
  46.             RDArgs *args;
  47.             Arg1 para;
  48.             rdargs->RDA_Source.CS_Buffer=var;
  49.             rdargs->RDA_Source.CS_Length=strlen(var);
  50.             rdargs->RDA_Source.CS_CurChr=0;
  51.             memset(¶,0,sizeof(Arg1));
  52.             if(args=ReadArgs("MODE/A/N,DITHER/A/N,DEPTH/A/N,DCT/A/N,SCALE/A/N,QUALITY/A/N,SMOOTH/A/N,GRAY/S,PROGRESSIVE/S",(long *)¶,rdargs))
  53.                 {
  54.                 data->mode=*para.mode;
  55.                 if(data->mode<0) data->mode=0;
  56.                 else if(data->mode>1) data->mode=1;
  57.                 data->dither=*para.dither;
  58.                 if(data->dither<0) data->dither=0;
  59.                 else if(data->dither>1) data->dither=1;
  60.                 data->depth=*para.depth;
  61.                 if(data->depth<3) data->depth=3;
  62.                 else if(data->depth>8) data->depth=8;
  63.                 data->dct=*para.dct;
  64.                 if(data->dct<0) data->dct=0;
  65.                 else if(data->dct>2) data->dct=2;
  66.                 data->scale=*para.scale;
  67.                 if(data->scale<0) data->scale=0;
  68.                 else if(data->scale>3) data->scale=3;
  69.                 data->scale=1<<data->scale;
  70.                 data->quality=*para.quality;
  71.                 if(data->quality<1) data->quality=1;
  72.                 else if(data->quality>100) data->quality=100;
  73.                 data->smooth=*para.smooth;
  74.                 if(data->smooth<0) data->smooth=0;
  75.                 else if(data->smooth>100) data->smooth=100;
  76.                 data->gray=para.gray;
  77.                 data->prog=para.prog;
  78.                 FreeArgs(args);
  79.                 }
  80.             FreeDosObject(DOS_RDARGS,rdargs);
  81.             }
  82.         }
  83.     FreeVec(var);
  84.     }
  85. if(SuperClassBase->lib_Version<43) data->mode=0;
  86. }
  87.  
  88. struct JPEGINFO
  89. {
  90. Object *obj;
  91. RastPort *rp,*trp;
  92. UBYTE *buffer;
  93. UWORD d,gray;
  94. };
  95.  
  96. static void _getline(UBYTE *scanline,ULONG y,ULONG numb,JPEGINFO *info)
  97. {
  98. if(info->gray) WritePixelLine8(info->rp,0,y,numb,scanline,info->trp);
  99. else
  100.     {
  101.     ULONG w=numb/3;
  102.     if(info->d>8) DoMethod(info->obj,PDTM_WRITEPIXELARRAY,scanline,RECTFMT_RGB,numb,0,y,w,1);
  103.     else
  104.         {
  105.         register ULONG i;
  106.         register UBYTE *p1,*p2;
  107.         p1=info->buffer+w*y*4;
  108.         p2=scanline;
  109.         for(i=0;i<w;i++,p1+=4,p2+=3)
  110.             {
  111.             p1[1]=p2[0];
  112.             p1[2]=p2[1];
  113.             p1[3]=p2[2];
  114.             }
  115.         }
  116.     }
  117. }
  118.  
  119. static ULONG getline(register __a0 UBYTE *scanline,register __d0 ULONG line,register __d1 ULONG numb,register __a1 void *userdata)
  120. {
  121. _getline(scanline,line-1,numb,(JPEGINFO *)userdata);
  122. return 0;
  123. }
  124.  
  125. ULONG Colors2DT(Object *obj,UBYTE *color)
  126. {
  127. UBYTE *cr;
  128. ULONG *cregs,i,num,error=0;
  129. GetDTAttrs(obj,PDTA_NumColors,&num,PDTA_ColorRegisters,&cr,PDTA_CRegs,&cregs,TAG_END);
  130. if(cr&&cregs)
  131.     {
  132.     if(color)
  133.         {
  134.         for(i=0;i<num;i++,cr+=3,cregs+=3,color+=4)
  135.             {
  136.             cr[0]=color[1];
  137.             cr[1]=color[2];
  138.             cr[2]=color[3];
  139.             cregs[0]=cr[0]<<24;
  140.             cregs[1]=cr[1]<<24;
  141.             cregs[2]=cr[2]<<24;
  142.             }
  143.         }
  144.     else
  145.         {
  146.         for(i=0;i<num;i++,cr+=3,cregs+=3)
  147.             {
  148.             cr[0]=i;
  149.             cr[1]=i;
  150.             cr[2]=i;
  151.             cregs[0]=i<<24;
  152.             cregs[1]=cregs[0];
  153.             cregs[2]=cregs[0];
  154.             }
  155.         }
  156.     }
  157. else error=ERROR_NO_FREE_STORE;
  158. return error;
  159. }
  160.  
  161. static void FillBMHD(Object *obj,BitMapHeader *bh,ULONG w,ULONG h,ULONG depth)
  162. {
  163. bh->bmh_Left=0;
  164. bh->bmh_Top=0;
  165. bh->bmh_Width=w;
  166. bh->bmh_Height=h;
  167. bh->bmh_PageWidth=w;
  168. bh->bmh_PageHeight=h;
  169. bh->bmh_Depth=depth;
  170. bh->bmh_Compression=cmpByteRun1;
  171. bh->bmh_XAspect=0;
  172. bh->bmh_YAspect=0;
  173. }
  174.  
  175. static void GetMode(Object *obj,BitMapHeader *bh,Data *data)
  176. {
  177. ULONG mode;
  178. mode=BestModeID(
  179. BIDTAG_NominalWidth,bh->bmh_PageWidth,BIDTAG_NominalHeight,bh->bmh_PageHeight,
  180. BIDTAG_DesiredWidth,bh->bmh_Width,BIDTAG_DesiredHeight,bh->bmh_Height,
  181. BIDTAG_Depth,bh->bmh_Depth,
  182. BIDTAG_DIPFMustNotHave,DIPF_IS_DUALPF|DIPF_IS_PF2PRI|DIPF_IS_HAM|DIPF_IS_EXTRAHALFBRITE,TAG_END);
  183. SetDTAttrs(obj,0,0,PDTA_ModeID,mode,TAG_END);
  184. if(bh->bmh_Depth<=8) SetDTAttrs(obj,0,0,PDTA_NumColors,1<<bh->bmh_Depth,TAG_END);
  185. }
  186.  
  187. static ULONG GetBody_Gray(JPEGDecHandle *jph,BitMapHeader *bh,BitMap *bm,Data *data)
  188. {
  189. ULONG error=0;
  190. UBYTE *buffer;
  191. RastPort rp;
  192. if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
  193.     {
  194.     if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
  195.         {
  196.         Chunky2BitMap(buffer,0,0,bh->bmh_Width,bh->bmh_Height,bm,0,0,TAG_END);
  197.         }
  198.     else error=ERROR_NO_FREE_STORE;
  199.     FreeJPEGBuffer(buffer);
  200.     }
  201. else
  202.     {
  203.     BitMap *tbm;
  204.     if(tbm=AllocBitMap(bh->bmh_Width,1,8,BMF_MINPLANES,bm))
  205.         {
  206.         RastPort trp;
  207.         InitRastPort(&rp);
  208.         InitRastPort(&trp);
  209.         rp.BitMap=bm;
  210.         trp.BitMap=tbm;
  211.         JPEGINFO info={0,&rp,&trp,0,8,1};
  212.         if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
  213.         FreeBitMap(tbm);
  214.         }
  215.     else error=ERROR_NO_FREE_STORE;
  216.     }
  217. return error;
  218. }
  219.  
  220. static ULONG GetBody_RGB(Object *obj,JPEGDecHandle *jph,BitMapHeader *bh,Data *data)
  221. {
  222. ULONG error=0;
  223. UBYTE *buffer;
  224. if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
  225.     {
  226.     if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
  227.         {
  228.         DoMethod(obj,PDTM_WRITEPIXELARRAY,buffer,RECTFMT_RGB,bh->bmh_Width*3,0,0,bh->bmh_Width,bh->bmh_Height);
  229.         }
  230.     else error=ERROR_NO_FREE_STORE;
  231.     FreeJPEGBuffer(buffer);
  232.     }
  233. else
  234.     {
  235.     JPEGINFO info={obj,0,0,0,24,0};
  236.     if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
  237.     }
  238. return error;
  239. }
  240.  
  241. static ULONG GetBody_RGB8(Object *obj,JPEGDecHandle *jph,BitMapHeader *bh,BitMap *bm,Data *data)
  242. {
  243. ULONG error=0;
  244. UBYTE *rgb;
  245. if(rgb=(UBYTE *)AllocVec(4*bh->bmh_Width*bh->bmh_Height,MEMF_CLEAR))
  246.     {
  247.     JPEGINFO info={obj,0,0,rgb,bh->bmh_Depth,0};
  248.     if(!DecompressJPEG(jph,
  249.         JPG_DecompressHook,getline,
  250.         JPG_DecompressUserData,&info,
  251.         JPG_ScaleDenom,data->scale,
  252.         JPG_DCTMethod,data->dct,
  253.         TAG_END))
  254.         {
  255.         APTR rmh;
  256.         if(rmh=CreateRMHandler(RND_MemType,RMHTYPE_POOL,TAG_END))
  257.             {
  258.             ULONG *palette;
  259.             if(palette=CreatePalette(RND_RMHandler,rmh,TAG_END))
  260.                 {
  261.                 APTR hst;
  262.                 if(hst=CreateHistogram(RND_RMHandler,rmh,TAG_END))
  263.                     {
  264.                     if(AddRGBImage(hst,(ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,TAG_END)==ADDH_SUCCESS)
  265.                         {
  266.                         ULONG numc;
  267.                         GetDTAttrs(obj,PDTA_NumColors,&numc,TAG_END);
  268.                         if(ExtractPalette(hst,palette,numc,TAG_END)==EXTP_SUCCESS)
  269.                             {
  270.                             UBYTE *chunky;
  271.                             if(chunky=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height,0))
  272.                                 {
  273.                                 if(Render((ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,chunky,palette,RND_DitherMode,data->dither,TAG_END)==REND_SUCCESS)
  274.                                     {
  275.                                     UBYTE *color;
  276.                                     if(color=(UBYTE *)AllocVec((1<<bh->bmh_Depth)*4,0))
  277.                                         {
  278.                                         ExportPalette(palette,color,TAG_END);
  279.                                         if(!(error=Colors2DT(obj,color))) Chunky2BitMap(chunky,0,0,bh->bmh_Width,bh->bmh_Height,bm,0,0,TAG_END);
  280.                                         FreeVec(color);
  281.                                         }
  282.                                     else error=ERROR_NO_FREE_STORE;
  283.                                     }
  284.                                 else error=ERROR_NO_FREE_STORE;
  285.                                 FreeVec(chunky);
  286.                                 }
  287.                             else error=ERROR_NO_FREE_STORE;
  288.                             }
  289.                         else error=ERROR_NO_FREE_STORE;
  290.                         }
  291.                     else error=ERROR_NO_FREE_STORE;
  292.                     DeleteHistogram(hst);
  293.                     }
  294.                 else error=ERROR_NO_FREE_STORE;
  295.                 DeletePalette(palette);
  296.                 }
  297.             else error=ERROR_NO_FREE_STORE;
  298.             DeleteRMHandler(rmh);
  299.             }
  300.         else error=ERROR_NO_FREE_STORE;
  301.         }
  302.     else error=ERROR_NO_FREE_STORE;
  303.     FreeVec(rgb);
  304.     }
  305. else error=ERROR_NO_FREE_STORE;
  306. return error;
  307. }
  308.  
  309. static ULONG GetPicture(IClass *cl,Object *obj)
  310. {
  311. ULONG error=0;
  312. long err;
  313. BPTR file;
  314. BitMapHeader *bh;
  315. GetDTAttrs(obj,DTA_Name,&bh,TAG_END);
  316. if(bh) SetDTAttrs(obj,0,0,DTA_ObjName,bh,TAG_END);
  317. GetDTAttrs(obj,DTA_Handle,&file,PDTA_BitMapHeader,&bh,TAG_END);
  318. if(bh)
  319.     {
  320.     JPEGDecHandle *jph;
  321.     if(!file)
  322.         {
  323.         GetDTAttrs(obj,DTA_SourceType,&err,TAG_END);
  324.         if(err!=DTST_RAM) return ERROR_REQUIRED_ARG_MISSING;
  325.         else return 0;
  326.         }
  327.     if(!AllocJPEGDecompress(&jph,JPG_SrcFile,file,TAG_END))
  328.         {
  329.         UBYTE colorspace;
  330.         ULONG w,h,bpp;
  331.         Data *data=(Data *)INST_DATA(cl,obj);
  332.         ReadPrefs(data);
  333.         if(!GetJPEGInfo(jph,JPG_Width,&w,JPG_Height,&h,JPG_ColourSpace,&colorspace,JPG_BytesPerPixel,&bpp,JPG_ScaleDenom,data->scale,TAG_END))
  334.             {
  335.             BitMap *bm;
  336.             switch(colorspace)
  337.                 {
  338.                 case JPCS_GRAYSCALE:
  339.                     FillBMHD(obj,bh,w,h,8);
  340.                     GetMode(obj,bh,data);
  341.                     if(bm=AllocBitMap(w,h,8,BMF_CLEAR|BMF_DISPLAYABLE|BMF_STANDARD,0))
  342.                         {
  343.                         Colors2DT(obj,0);
  344.                         SetDTAttrs(obj,0,0,DTA_NominalHoriz,w,DTA_NominalVert,h,PDTA_BitMap,bm,TAG_END);
  345.                         error=GetBody_Gray(jph,bh,bm,data);
  346.                         }
  347.                     else error=ERROR_NO_FREE_STORE;
  348.                     break;
  349.                 case JPCS_RGB:
  350.                     if(data->mode)
  351.                         {
  352.                         FillBMHD(obj,bh,w,h,24);
  353.                         SetDTAttrs(obj,0,0,DTA_ErrorNumber,&error,DTA_NominalHoriz,w,DTA_NominalVert,h,PDTA_SourceMode,PMODE_V43,PDTA_ModeID,0,TAG_END);
  354.                         if(!error) error=GetBody_RGB(obj,jph,bh,data);
  355.                         }
  356.                     else
  357.                         {
  358.                         FillBMHD(obj,bh,w,h,data->depth);
  359.                         GetMode(obj,bh,data);
  360.                         if(bm=AllocBitMap(w,h,data->depth,BMF_CLEAR|BMF_DISPLAYABLE|BMF_STANDARD,0))
  361.                             {
  362.                             SetDTAttrs(obj,0,0,DTA_NominalHoriz,w,DTA_NominalVert,h,PDTA_BitMap,bm,TAG_END);
  363.                             error=GetBody_RGB8(obj,jph,bh,bm,data);
  364.                             }
  365.                         else error=ERROR_NO_FREE_STORE;
  366.                         }
  367.                     break;
  368.                 default:
  369.                     error=ERROR_NOT_IMPLEMENTED;
  370.                 }
  371.             }
  372.         else error=DTERROR_INVALID_DATA;
  373.         }
  374.     else error=DTERROR_INVALID_DATA;
  375.     }
  376. else error=ERROR_NO_FREE_STORE;
  377. return error;
  378. }
  379.  
  380. static ULONG mNew(IClass *cl,Object *obj,opSet *msg)
  381. {
  382. TagItem *ti;
  383. if(ti=FindTagItem(DTA_SourceType,(((opSet *)msg)->ops_AttrList)))
  384.     {
  385.     if(ti->ti_Data!=DTST_FILE&&ti->ti_Data!=DTST_CLIPBOARD&&ti->ti_Data!=DTST_RAM)
  386.         {
  387.         SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  388.         return 0;
  389.         }
  390.     }
  391. if(obj==(Object *)cl)
  392.     {
  393.     if(obj=(Object *)DoSuperMethodA(cl,obj,Msg(msg)))
  394.         {
  395.         ULONG error;
  396.         if(error=GetPicture(cl,obj))
  397.             {
  398.             SetIoErr(error);
  399.             CoerceMethod(cl,obj,OM_DISPOSE);
  400.             obj=0;
  401.             }
  402.         }
  403.     }
  404. else
  405.     {
  406.     SetIoErr(ERROR_NOT_IMPLEMENTED);
  407.     obj=0;
  408.     }
  409. return ULONG(obj);
  410. }
  411.  
  412. static ULONG mSet(IClass *cl,Object *obj,opSet *msg)
  413. {
  414. ULONG retval;
  415. if(retval=DoSuperMethodA(cl,obj,Msg(msg)))
  416.     {
  417.     RastPort *rp;
  418.     if(rp=ObtainGIRPort(msg->ops_GInfo))
  419.         {
  420.         DoMethod(obj,GM_RENDER,msg->ops_GInfo,rp,GREDRAW_UPDATE);
  421.         ReleaseGIRPort(rp);
  422.         retval=0;
  423.         }
  424.     }
  425. return retval;
  426. }
  427.  
  428. static ULONG mWrite(IClass *cl,Object *obj,dtWrite *msg)
  429. {
  430. return (msg->dtw_Mode==DTWM_IFF)?DoSuperMethodA(cl,obj,Msg(msg)):SaveJPEG(cl,obj,msg);
  431. }
  432.  
  433. extern "C" ULONG Dispatcher(register __a0 IClass *cl,register __a2 Object *obj,register __a1 Msg msg)
  434. {
  435. ULONG retval;
  436. switch(msg->MethodID)
  437.     {
  438.     case OM_NEW:
  439.         retval=mNew(cl,obj,(opSet *)msg);
  440.         break;
  441.     case OM_UPDATE:
  442.         if(DoMethod(obj,ICM_CHECKLOOP)) break;
  443.     case OM_SET:
  444.         retval=mSet(cl,obj,(opSet *)msg);
  445.         break;
  446.     case DTM_WRITE:
  447.         retval=mWrite(cl,obj,(dtWrite *)msg);
  448.         break;
  449.     default:
  450.         retval=DoSuperMethodA(cl,obj,msg);
  451.         }
  452. return retval;
  453. }
  454.  
  455.