home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_3.5 / Examples / Icon / ImageToIcon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-30  |  16.7 KB  |  819 lines

  1. /*
  2.  * $Id$
  3.  *
  4.  * :ts=4
  5.  *
  6.  * COPYRIGHT:
  7.  *
  8.  *   Unless otherwise noted, all files are Copyright (c) 1999 Amiga, Inc.
  9.  *   All rights reserved.
  10.  *
  11.  * DISCLAIMER:
  12.  *
  13.  *   This software is provided "as is". No representations or warranties
  14.  *   are made with respect to the accuracy, reliability, performance,
  15.  *   currentness, or operation of this software, and all use is at your
  16.  *   own risk. Neither Amiga nor the authors assume any responsibility
  17.  *   or liability whatsoever with respect to your use of this software.
  18.  *
  19.  */
  20.  
  21. #include <dos/dosextens.h>
  22. #include <dos/dosasl.h>
  23. #include <dos/rdargs.h>
  24.  
  25. #include <exec/memory.h>
  26.  
  27. #include <workbench/workbench.h>
  28.  
  29. #include <intuition/gadgetclass.h>
  30.  
  31. #include <datatypes/datatypes.h>
  32. #include <datatypes/pictureclass.h>
  33.  
  34. #include <clib/exec_protos.h>
  35. #include <clib/intuition_protos.h>
  36. #include <clib/datatypes_protos.h>
  37. #include <clib/utility_protos.h>
  38. #include <clib/graphics_protos.h>
  39. #include <clib/dos_protos.h>
  40. #include <clib/alib_protos.h>
  41.  
  42. #include <pragmas/exec_sysbase_pragmas.h>
  43. #include <pragmas/intuition_pragmas.h>
  44. #include <pragmas/datatypes_pragmas.h>
  45. #include <pragmas/utility_pragmas.h>
  46. #include <pragmas/graphics_pragmas.h>
  47. #include <pragmas/dos_pragmas.h>
  48.  
  49. #define USE_BUILTIN_MATH
  50. #include <string.h>
  51.  
  52. /****************************************************************************/
  53.  
  54. extern struct Library * SysBase;
  55. extern struct Library * DOSBase;
  56. extern struct Library * UtilityBase;
  57. extern struct Library * DataTypesBase;
  58. extern struct Library * IntuitionBase;
  59. extern struct Library * GfxBase;
  60. extern struct Library * IconBase;
  61.  
  62. /****************************************************************************/
  63.  
  64. #include <workbench/icon.h>
  65. #include <clib/icon_protos.h>
  66. #include <pragmas/icon_pragmas.h>
  67.  
  68. /****************************************************************************/
  69.  
  70. #define CANNOT !
  71. #define OK (0)
  72. #define SAME (0)
  73.  
  74. /****************************************************************************/
  75.  
  76. UBYTE Default4Palette[4][3] =
  77. {
  78.     0xAA,0xAA,0xAA,
  79.     0x00,0x00,0x00,
  80.     0xFF,0xFF,0xFF,
  81.     0x65,0x8A,0xBA
  82. };
  83.  
  84. /****************************************************************************/
  85.  
  86. #define MM 2147483647    /* a Mersenne prime */
  87. #define AA 48271        /* this does well in the spectral test */
  88. #define QQ 44488        /* (long)(MM/AA) */
  89. #define RR 3399            /* MM % AA; it is important that RR < QQ */
  90.  
  91. STATIC LONG X;
  92.  
  93. VOID
  94. SetRandomSeed(LONG seed)
  95. {
  96.     X = (seed % MM);
  97. }
  98.  
  99. LONG
  100. Random(LONG maxValue)
  101. {
  102.     X = AA * (X % QQ) - RR * (LONG)(X / QQ);
  103.     if(X < 0)
  104.         X += MM;
  105.  
  106.     return(X % maxValue);
  107. }
  108.  
  109. /****************************************************************************/
  110.  
  111. VOID
  112. ImageToBitMap(
  113.     struct Image *    image,
  114.     struct BitMap *    bitMap)
  115. {
  116.     PLANEPTR plane;
  117.     LONG pageSize;
  118.     LONG i;
  119.  
  120.     memset(bitMap,0,sizeof(*bitMap));
  121.  
  122.     bitMap->BytesPerRow    = RASSIZE(image->Width,1);
  123.     bitMap->Rows        = image->Height;
  124.     bitMap->Depth        = image->Depth;
  125.  
  126.     pageSize = RASSIZE(image->Width,image->Height);
  127.     plane = (PLANEPTR)image->ImageData;
  128.  
  129.     for(i = 0 ; i < image->Depth ; i++)
  130.     {
  131.         bitMap->Planes[i] = plane;
  132.  
  133.         plane += pageSize;
  134.     }
  135. }
  136.  
  137. /****************************************************************************/
  138.  
  139. VOID
  140. DeleteImage(struct Image * image)
  141. {
  142.     if(image != NULL)
  143.     {
  144.         if(image->ImageData)
  145.         {
  146.             LONG numBytes = RASSIZE(image->Width,image->Height) * image->Depth;
  147.  
  148.             WaitBlit();
  149.  
  150.             FreeMem(image->ImageData,numBytes);
  151.         }
  152.  
  153.         FreeVec(image);
  154.     }
  155. }
  156.  
  157. struct Image *
  158. CreateImage(LONG depth,LONG width,LONG height)
  159. {
  160.     struct Image * result = NULL;
  161.     struct Image * image;
  162.  
  163.     image = AllocVec(sizeof(*image),MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR);
  164.     if(image != NULL)
  165.     {
  166.         LONG numBytes;
  167.  
  168.         image->Width        = width;
  169.         image->Height        = height;
  170.         image->Depth        = depth;
  171.         image->PlanePick    = (1L<<depth)-1;
  172.  
  173.         numBytes = RASSIZE(width,height) * depth;
  174.         image->ImageData = AllocMem(numBytes,MEMF_CHIP);
  175.         if(image->ImageData != NULL)
  176.         {
  177.             BltClear((PLANEPTR)image->ImageData,numBytes,1);
  178.             result = image;
  179.         }
  180.     }
  181.  
  182.     if(result == NULL)
  183.         DeleteImage(image);
  184.  
  185.     return(result);
  186. }
  187.  
  188. /****************************************************************************/
  189.  
  190. typedef STRPTR    KEY;
  191. typedef LONG    SWITCH;
  192.  
  193. /****************************************************************************/
  194.  
  195. struct RGBDelta
  196. {
  197.     LONG red;
  198.     LONG green;
  199.     LONG blue;
  200. };
  201.  
  202. /****************************************************************************/
  203.  
  204. STATIC int __inline
  205. clamp(int x)
  206. {
  207.     if (x < 0)
  208.         return(0);
  209.     else if (x > 255)
  210.         return(255);
  211.     else
  212.         return(x);
  213. }
  214.  
  215. /****************************************************************************/
  216.  
  217. LONG
  218. DitherToImage(struct BitMap * bmap,struct ColorRegister * cmap,LONG numColours,LONG width,LONG height,struct Image * image)
  219. {
  220.     struct RastPort rp;
  221.     struct RastPort rp2;
  222.     struct BitMap bmap2;
  223.     int x,y,i,pen,d,delta,best,r,g,b,r2,g2,b2;
  224.     struct RGBDelta * rows[2];
  225.     struct RGBDelta * row1;
  226.     struct RGBDelta * row2;
  227.     struct RGBDelta * swap;
  228.     LONG error = OK;
  229.  
  230.     memset(rows,0,sizeof(rows));
  231.  
  232.     rows[0] = AllocVec(sizeof(*rows[0]) * (2 + width),MEMF_ANY|MEMF_CLEAR);
  233.     rows[1] = AllocVec(sizeof(*rows[1]) * (2 + width),MEMF_ANY|MEMF_CLEAR);
  234.  
  235.     if(rows[0] == NULL || rows[1] == NULL)
  236.     {
  237.         error = ERROR_NO_FREE_STORE;
  238.         goto out;
  239.     }
  240.  
  241.     row1 = rows[0] + 1;
  242.     row2 = rows[1] + 1;
  243.  
  244.     InitRastPort(&rp);
  245.     rp.BitMap = bmap;
  246.  
  247.     ImageToBitMap(image,&bmap2);
  248.     InitRastPort(&rp2);
  249.     rp2.BitMap = &bmap2;
  250.  
  251.     SetABPenDrMd(&rp2,0,0,JAM2);
  252.  
  253.     for(x = 0 ; x < width ; x++)
  254.     {
  255.         row1[x].red        = Random(127) - 63;
  256.         row1[x].green    = Random(127) - 63;
  257.         row1[x].blue    = Random(127) - 63;
  258.     }
  259.  
  260.     for(y = 0 ; y < height ; y++)
  261.     {
  262.         if((y % 2) == 0)
  263.         {
  264.             for(x = 0 ; x < width ; x++)
  265.             {
  266.                 pen = ReadPixel(&rp,x,y);
  267.  
  268.                 r = clamp(cmap[pen].red        + row1[x].red    / 16);
  269.                 g = clamp(cmap[pen].green    + row1[x].green    / 16);
  270.                 b = clamp(cmap[pen].blue    + row1[x].blue    / 16);
  271.  
  272.                 best = delta = 0;
  273.  
  274.                 for(i = 0 ; i < 4 ; i++)
  275.                 {
  276.                     d = abs(r - Default4Palette[i][0]) +
  277.                         abs(g - Default4Palette[i][1]) +
  278.                         abs(b - Default4Palette[i][2]);
  279.  
  280.                     if(i == 0 || d < delta)
  281.                     {
  282.                         delta = d;
  283.                         best = i;
  284.                     }
  285.                 }
  286.  
  287.                 SetAPen(&rp2,best);
  288.                 WritePixel(&rp2,x,y);
  289.  
  290.                 r2 = Default4Palette[best][0];
  291.                 g2 = Default4Palette[best][1];
  292.                 b2 = Default4Palette[best][2];
  293.  
  294.                 row1[x+1].red    += (r - r2) * 7;
  295.                 row1[x+1].green    += (g - g2) * 7;
  296.                 row1[x+1].blue    += (b - b2) * 7;
  297.  
  298.                 row2[x-1].red    += (r - r2) * 3;
  299.                 row2[x-1].green    += (g - g2) * 3;
  300.                 row2[x-1].blue    += (b - b2) * 3;
  301.  
  302.                 row2[x  ].red    += (r - r2) * 5;
  303.                 row2[x  ].green    += (g - g2) * 5;
  304.                 row2[x  ].blue    += (b - b2) * 5;
  305.  
  306.                 row2[x+1].red    += (r - r2);
  307.                 row2[x+1].green    += (g - g2);
  308.                 row2[x+1].blue    += (b - b2);
  309.             }
  310.         }
  311.         else
  312.         {
  313.             for(x = width - 1 ; x >= 0 ; x--)
  314.             {
  315.                 pen = ReadPixel(&rp,x,y);
  316.  
  317.                 r = clamp(cmap[pen].red        + row1[x].red    / 16);
  318.                 g = clamp(cmap[pen].green    + row1[x].green    / 16);
  319.                 b = clamp(cmap[pen].blue    + row1[x].blue    / 16);
  320.  
  321.                 best = delta = 0;
  322.  
  323.                 for(i = 0 ; i < 4 ; i++)
  324.                 {
  325.                     d = abs(r - Default4Palette[i][0]) +
  326.                         abs(g - Default4Palette[i][1]) +
  327.                         abs(b - Default4Palette[i][2]);
  328.  
  329.                     if(i == 0 || d < delta)
  330.                     {
  331.                         delta = d;
  332.                         best = i;
  333.                     }
  334.                 }
  335.  
  336.                 SetAPen(&rp2,best);
  337.                 WritePixel(&rp2,x,y);
  338.  
  339.                 r2 = Default4Palette[best][0];
  340.                 g2 = Default4Palette[best][1];
  341.                 b2 = Default4Palette[best][2];
  342.  
  343.                 row1[x-1].red    += (r - r2) * 7;
  344.                 row1[x-1].green    += (g - g2) * 7;
  345.                 row1[x-1].blue    += (b - b2) * 7;
  346.  
  347.                 row2[x+1].red    += (r - r2) * 3;
  348.                 row2[x+1].green    += (g - g2) * 3;
  349.                 row2[x+1].blue    += (b - b2) * 3;
  350.  
  351.                 row2[x  ].red    += (r - r2) * 5;
  352.                 row2[x  ].green    += (g - g2) * 5;
  353.                 row2[x  ].blue    += (b - b2) * 5;
  354.  
  355.                 row2[x-1].red    += (r - r2);
  356.                 row2[x-1].green    += (g - g2);
  357.                 row2[x-1].blue    += (b - b2);
  358.             }
  359.         }
  360.  
  361.         swap = row1;
  362.         row1 = row2;
  363.         row2 = swap;
  364.  
  365.         memset(row2,0,sizeof(*row2) * width);
  366.     }
  367.  
  368.  out:
  369.  
  370.     FreeVec(rows[0]);
  371.     FreeVec(rows[1]);
  372.  
  373.     return(error);
  374. }
  375.  
  376. VOID
  377. RemapToImage(struct BitMap * bmap,struct ColorRegister * cmap,LONG numColours,LONG width,LONG height,struct Image * image)
  378. {
  379.     struct RastPort rp;
  380.     struct RastPort rp2;
  381.     struct BitMap bmap2;
  382.     int x,y,i,pen,d,delta,best,r,g,b;
  383.  
  384.     InitRastPort(&rp);
  385.     rp.BitMap = bmap;
  386.  
  387.     ImageToBitMap(image,&bmap2);
  388.     InitRastPort(&rp2);
  389.     rp2.BitMap = &bmap2;
  390.  
  391.     SetABPenDrMd(&rp2,0,0,JAM2);
  392.  
  393.     for(y = 0 ; y < height ; y++)
  394.     {
  395.         for(x = 0 ; x < width ; x++)
  396.         {
  397.             pen = ReadPixel(&rp,x,y);
  398.  
  399.             r = cmap[pen].red;
  400.             g = cmap[pen].green;
  401.             b = cmap[pen].blue;
  402.  
  403.             best = delta = 0;
  404.  
  405.             for(i = 0 ; i < 4 ; i++)
  406.             {
  407.                 d = abs(r - Default4Palette[i][0]) +
  408.                     abs(g - Default4Palette[i][1]) +
  409.                     abs(b - Default4Palette[i][2]);
  410.  
  411.                 if(i == 0 || d < delta)
  412.                 {
  413.                     delta = d;
  414.                     best = i;
  415.                 }
  416.             }
  417.  
  418.             SetAPen(&rp2,best);
  419.             WritePixel(&rp2,x,y);
  420.         }
  421.     }
  422. }
  423.  
  424. /****************************************************************************/
  425.  
  426. int
  427. main(int argc,char **argv)
  428. {
  429.     struct { STRPTR Name; LONG ID; } TypeTable[] =
  430.     {
  431.         "DISK",        WBDISK,
  432.         "DRAWER",    WBDRAWER,
  433.         "TOOL",        WBTOOL,
  434.         "PROJECT",    WBPROJECT,
  435.         "TRASH",    WBGARBAGE,
  436.         "TRASHCAN",    WBGARBAGE,
  437.         "GARBAGE",    WBGARBAGE,
  438.         "DEVICE",    WBDEVICE,
  439.         NULL
  440.     };
  441.  
  442.     struct { KEY Image1; KEY Image2; KEY To; SWITCH Borderless; SWITCH Dither; KEY Type; } args;
  443.     struct RDArgs * rda = NULL;
  444.     int result = RETURN_FAIL;
  445.     Object * picture1 = NULL;
  446.     Object * picture2 = NULL;
  447.     LONG error = OK;
  448.     struct dtFrameBox dtf;
  449.     struct FrameInfo fri;
  450.     struct BitMapHeader * bmh1 = NULL;
  451.     struct BitMapHeader * bmh2 = NULL;
  452.     struct ColorRegister * cmap1 = NULL;
  453.     struct ColorRegister * cmap2 = NULL;
  454.     struct BitMap * bmap1 = NULL;
  455.     struct BitMap * bmap2 = NULL;
  456.     LONG numColours1 = 0;
  457.     LONG numColours2 = 0;
  458.     struct gpLayout gpl;
  459.     struct DiskObject * icon = NULL;
  460.     UBYTE * buffer1 = NULL;
  461.     UBYTE * buffer2 = NULL;
  462.     struct Image * image1 = NULL;
  463.     struct Image * image2 = NULL;
  464.     int x,y;
  465.     struct RastPort rp;
  466.     UBYTE * t;
  467.     LONG type;
  468.     int i;
  469.     ULONG a,b;
  470.  
  471.     if(IconBase->lib_Version < 44)
  472.     {
  473.         Printf("Could not open icon.library V44\n");
  474.         goto out;
  475.     }
  476.  
  477.     CurrentTime(&a,&b);
  478.     SetRandomSeed(a+b);
  479.  
  480.     memset(&args,0,sizeof(args));
  481.  
  482.     rda = ReadArgs("IMAGE1,IMAGE2,TO/A,BORDERLESS/S,DITHER/S,TYPE/K",(LONG *)&args,NULL);
  483.     if(rda == NULL)
  484.     {
  485.         error = IoErr();
  486.         goto out;
  487.     }
  488.  
  489.     type = WBTOOL;
  490.  
  491.     if(args.Type != NULL)
  492.     {
  493.         for(i = 0 ; TypeTable[i].Name != NULL ; i++)
  494.         {
  495.             if(Stricmp(TypeTable[i].Name,args.Type) == SAME)
  496.             {
  497.                 type = TypeTable[i].ID;
  498.                 break;
  499.             }
  500.         }
  501.     }
  502.  
  503.     if(args.Image1 == NULL)
  504.     {
  505.         error = ERROR_REQUIRED_ARG_MISSING;
  506.         goto out;
  507.     }
  508.  
  509.     picture1 = NewDTObject(args.Image1,
  510.         DTA_SourceType,    DTST_FILE,
  511.         DTA_GroupID,    GID_PICTURE,
  512.         PDTA_Remap,        FALSE,
  513.     TAG_DONE);
  514.     if(picture1 == NULL)
  515.     {
  516.         error = IoErr();
  517.         goto out;
  518.     }
  519.  
  520.     memset(&dtf,0,sizeof(dtf));
  521.  
  522.     memset(&fri,0,sizeof(fri));
  523.  
  524.     dtf.MethodID            = DTM_FRAMEBOX;
  525.     dtf.dtf_FrameInfo        = &fri;
  526.     dtf.dtf_ContentsInfo    = &fri;
  527.     dtf.dtf_SizeFrameInfo    = sizeof(fri);
  528.  
  529.     if(CANNOT DoMethodA(picture1,(Msg)&dtf))
  530.     {
  531.         Printf("%s: Could not frame object\n",args.Image1);
  532.         error = -1;
  533.         goto out;
  534.     }
  535.  
  536.     if(fri.fri_Dimensions.Depth < 1 || fri.fri_Dimensions.Depth > 8)
  537.     {
  538.         Printf("%s: Unsupported depth (%ld)\n",args.Image1,fri.fri_Dimensions.Depth);
  539.         error = -1;
  540.         goto out;
  541.     }
  542.  
  543.     if((fri.fri_PropertyFlags & DIPF_IS_HAM) ||
  544.        (fri.fri_PropertyFlags & DIPF_IS_EXTRAHALFBRITE))
  545.     {
  546.         Printf("%s: Cannot handle HAM/Extra Halfbrite\n",args.Image1);
  547.         error = -1;
  548.         goto out;
  549.     }
  550.  
  551.     memset(&gpl,0,sizeof(gpl));
  552.  
  553.     gpl.MethodID    = DTM_PROCLAYOUT;
  554.     gpl.gpl_GInfo    = NULL;
  555.     gpl.gpl_Initial    = 1;
  556.  
  557.     if(CANNOT DoMethodA(picture1,(Msg)&gpl))
  558.     {
  559.         Printf("%s: Could not layout object\n",args.Image1);
  560.         error = -1;
  561.         goto out;
  562.     }
  563.  
  564.     GetDTAttrs(picture1,
  565.         PDTA_NumColors,        &numColours1,
  566.         PDTA_ColorRegisters,&cmap1,
  567.         PDTA_BitMapHeader,    &bmh1,
  568.         PDTA_BitMap,        &bmap1,
  569.     TAG_DONE);
  570.  
  571.     if(numColours1 == 0 || cmap1 == NULL || bmh1 == NULL || bmap1 == NULL)
  572.     {
  573.         Printf("%s: Invalid object data\n",args.Image1);
  574.         error = -1;
  575.         goto out;
  576.     }
  577.  
  578.     if(args.Image2 != NULL)
  579.     {
  580.         picture2 = NewDTObject(args.Image2,
  581.             DTA_SourceType,    DTST_FILE,
  582.             DTA_GroupID,    GID_PICTURE,
  583.             PDTA_Remap,        FALSE,
  584.         TAG_DONE);
  585.         if(picture2 == NULL)
  586.         {
  587.             error = IoErr();
  588.             goto out;
  589.         }
  590.  
  591.         memset(&dtf,0,sizeof(dtf));
  592.  
  593.         memset(&fri,0,sizeof(fri));
  594.  
  595.         dtf.MethodID            = DTM_FRAMEBOX;
  596.         dtf.dtf_FrameInfo        = &fri;
  597.         dtf.dtf_ContentsInfo    = &fri;
  598.         dtf.dtf_SizeFrameInfo    = sizeof(fri);
  599.  
  600.         if(CANNOT DoMethodA(picture2,(Msg)&dtf))
  601.         {
  602.             Printf("%s: Could not frame object\n",args.Image2);
  603.             error = -1;
  604.             goto out;
  605.         }
  606.  
  607.         if(fri.fri_Dimensions.Depth < 1 || fri.fri_Dimensions.Depth > 8)
  608.         {
  609.             Printf("%s: Unsupported depth (%ld)\n",args.Image2,fri.fri_Dimensions.Depth);
  610.             error = -1;
  611.             goto out;
  612.         }
  613.  
  614.         if((fri.fri_PropertyFlags & DIPF_IS_HAM) ||
  615.            (fri.fri_PropertyFlags & DIPF_IS_EXTRAHALFBRITE))
  616.         {
  617.             Printf("%s: Cannot handle HAM/Extra Halfbrite\n",args.Image2);
  618.             error = -1;
  619.             goto out;
  620.         }
  621.  
  622.         memset(&gpl,0,sizeof(gpl));
  623.  
  624.         gpl.MethodID    = DTM_PROCLAYOUT;
  625.         gpl.gpl_GInfo    = NULL;
  626.         gpl.gpl_Initial    = 1;
  627.  
  628.         if(CANNOT DoMethodA(picture2,(Msg)&gpl))
  629.         {
  630.             Printf("%s: Could not layout object\n",args.Image2);
  631.             error = -1;
  632.             goto out;
  633.         }
  634.  
  635.         GetDTAttrs(picture2,
  636.             PDTA_NumColors,        &numColours2,
  637.             PDTA_ColorRegisters,&cmap2,
  638.             PDTA_BitMapHeader,    &bmh2,
  639.             PDTA_BitMap,        &bmap2,
  640.         TAG_DONE);
  641.  
  642.         if(numColours2 == 0 || cmap2 == NULL || bmh2 == NULL || bmap2 == NULL)
  643.         {
  644.             Printf("%s: Invalid object data\n",args.Image2);
  645.             error = -1;
  646.             goto out;
  647.         }
  648.  
  649.         if(numColours1 != numColours2)
  650.         {
  651.             Printf("%s: \"%s\" and \"%s\" do not use the same number of colours\n",FilePart(argv[0]),args.Image1,args.Image2);
  652.             error = -1;
  653.             goto out;
  654.         }
  655.  
  656.         if(bmh1->bmh_Width != bmh2->bmh_Width || bmh1->bmh_Height != bmh2->bmh_Height)
  657.         {
  658.             Printf("%s: \"%s\" and \"%s\" are not the same size\n",FilePart(argv[0]),args.Image1,args.Image2);
  659.             error = -1;
  660.             goto out;
  661.         }
  662.  
  663.         buffer2 = AllocVec(bmh1->bmh_Width * bmh1->bmh_Height,MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR);
  664.         if(buffer2 == NULL)
  665.         {
  666.             error = ERROR_NO_FREE_STORE;
  667.             goto out;
  668.         }
  669.  
  670.         image2 = CreateImage(2,bmh1->bmh_Width,bmh1->bmh_Height);
  671.         if(image2 == NULL)
  672.         {
  673.             error = ERROR_NO_FREE_STORE;
  674.             goto out;
  675.         }
  676.     }
  677.  
  678.     image1 = CreateImage(2,bmh1->bmh_Width,bmh1->bmh_Height);
  679.     if(image1 == NULL)
  680.     {
  681.         error = ERROR_NO_FREE_STORE;
  682.         goto out;
  683.     }
  684.  
  685.     if(args.Dither)
  686.     {
  687.         error = DitherToImage(bmap1,cmap1,numColours1,bmh1->bmh_Width,bmh1->bmh_Height,image1);
  688.         if(error != OK)
  689.             goto out;
  690.  
  691.         if(image2 != NULL)
  692.         {
  693.             error = DitherToImage(bmap2,cmap2,numColours2,bmh1->bmh_Width,bmh1->bmh_Height,image2);
  694.             if(error != OK)
  695.                 goto out;
  696.         }
  697.     }
  698.     else
  699.     {
  700.         RemapToImage(bmap1,cmap1,numColours1,bmh1->bmh_Width,bmh1->bmh_Height,image1);
  701.  
  702.         if(image2 != NULL)
  703.             RemapToImage(bmap2,cmap2,numColours2,bmh1->bmh_Width,bmh1->bmh_Height,image2);
  704.     }
  705.  
  706.     buffer1 = AllocVec(bmh1->bmh_Width * bmh1->bmh_Height,MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR);
  707.     if(buffer1 == NULL)
  708.     {
  709.         error = ERROR_NO_FREE_STORE;
  710.         goto out;
  711.     }
  712.  
  713.     icon = GetDefDiskObject(type);
  714.     if(icon == NULL)
  715.     {
  716.         error = IoErr();
  717.         goto out;
  718.     }
  719.  
  720.     InitRastPort(&rp);
  721.     rp.BitMap = bmap1;
  722.  
  723.     t = buffer1;
  724.  
  725.     for(y = 0 ; y < bmh1->bmh_Height ; y++)
  726.     {
  727.         for(x = 0 ; x < bmh1->bmh_Width ; x++)
  728.             (*t++) = ReadPixel(&rp,x,y);
  729.     }
  730.  
  731.     if(picture2 != NULL)
  732.     {
  733.         rp.BitMap = bmap2;
  734.     
  735.         t = buffer2;
  736.     
  737.         for(y = 0 ; y < bmh1->bmh_Height ; y++)
  738.         {
  739.             for(x = 0 ; x < bmh1->bmh_Width ; x++)
  740.                 (*t++) = ReadPixel(&rp,x,y);
  741.         }
  742.     }
  743.  
  744.     IconControl(icon,
  745.         ICONCTRLA_SetWidth,            bmh1->bmh_Width,
  746.         ICONCTRLA_SetHeight,        bmh1->bmh_Height,
  747.         ICONCTRLA_SetAspectRatio,    PACK_ICON_ASPECT_RATIO(1,1),
  748.         ICONCTRLA_SetImageData1,    buffer1,
  749.         ICONCTRLA_SetPaletteSize1,    numColours1,
  750.         ICONCTRLA_SetPalette1,        cmap1,
  751.         ICONCTRLA_SetTransparentColor1,(bmh1->bmh_Masking == mskHasTransparentColor) ? bmh1->bmh_Transparent : -1,
  752.         ICONCTRLA_SetFrameless,        args.Borderless,
  753.         ICONA_ErrorCode,            &error,
  754.     TAG_DONE);
  755.     if(error != OK)
  756.         goto out;
  757.  
  758.     if(picture2 != NULL)
  759.     {
  760.         IconControl(icon,
  761.             ICONCTRLA_SetImageData2,    buffer2,
  762.             ICONCTRLA_SetPaletteSize2,    numColours2,
  763.             ICONCTRLA_SetPalette2,        cmap2,
  764.             ICONCTRLA_SetTransparentColor2,(bmh2->bmh_Masking == mskHasTransparentColor) ? bmh2->bmh_Transparent : -1,
  765.             ICONA_ErrorCode,            &error,
  766.         TAG_DONE);
  767.         if(error != OK)
  768.             goto out;
  769.     }
  770.  
  771.     icon->do_Gadget.Width            = image1->Width;
  772.     icon->do_Gadget.Height            = image1->Height;
  773.     icon->do_Gadget.GadgetRender    = image1;
  774.  
  775.     if(image2 != NULL)
  776.     {
  777.         icon->do_Gadget.Flags = (icon->do_Gadget.Flags & ~GFLG_GADGHIGHBITS) | GFLG_GADGHIMAGE;
  778.         icon->do_Gadget.SelectRender = image2;
  779.     }
  780.     else
  781.     {
  782.         icon->do_Gadget.Flags = (icon->do_Gadget.Flags & ~GFLG_GADGHIGHBITS) | GFLG_GADGHCOMP;
  783.         icon->do_Gadget.SelectRender = NULL;
  784.     }
  785.  
  786.     PutIconTags(args.To,icon,
  787.         ICONA_ErrorCode,&error,
  788.         ICONPUTA_NotifyWorkbench,TRUE,
  789.     TAG_DONE);
  790.     if(error != OK)
  791.         goto out;
  792.  
  793.     result = RETURN_OK;
  794.  
  795.  out:
  796.  
  797.     if(picture1 != NULL)
  798.         DisposeDTObject(picture1);
  799.  
  800.     if(picture2 != NULL)
  801.         DisposeDTObject(picture2);
  802.  
  803.     FreeVec(buffer1);
  804.     FreeVec(buffer2);
  805.  
  806.     if(icon != NULL)
  807.         FreeDiskObject(icon);
  808.  
  809.     DeleteImage(image1);
  810.     DeleteImage(image2);
  811.  
  812.     FreeArgs(rda);
  813.  
  814.     if(error != OK && error != -1)
  815.         PrintFault(error,FilePart(argv[0]));
  816.  
  817.     return(result);
  818. }
  819.