Initial import of Scalos. To decrease size I have
[AROS-Contrib.git] / scalos / datatypes / GlowIconObject / GlowIconObject.c
blob6a738e8cf72c207d4b3279d336f63f58b1c88deb
1 // GlowIconObject.c
2 // $Date$
3 // $Revision$
6 #include <exec/types.h>
7 #include <exec/resident.h>
8 #include <graphics/gfxbase.h>
9 #include <graphics/rastport.h>
10 #include <graphics/rpattr.h>
11 #include <intuition/classes.h>
12 #include <intuition/classusr.h>
13 #include <intuition/gadgetclass.h>
14 #include <workbench/workbench.h>
15 #include <workbench/icon.h>
16 #include <libraries/iffparse.h>
17 #include <datatypes/iconobject.h>
18 #include <cybergraphx/cybergraphics.h>
20 #define __USE_SYSBASE
21 #include <proto/graphics.h>
22 #include <proto/utility.h>
23 #include <proto/exec.h>
24 #include <proto/dos.h>
25 #include <proto/cybergraphics.h>
26 #include <proto/iffparse.h>
27 #include <proto/wb.h>
28 #include <proto/timer.h>
30 #include <clib/alib_protos.h>
32 #include <proto/exec.h>
33 #include <proto/graphics.h>
34 #include <proto/intuition.h>
35 #include <proto/utility.h>
36 #include <proto/icon.h>
38 #include <string.h>
39 #include <ctype.h>
41 #include <defs.h>
42 #include <Year.h>
43 #include <zlib.h>
45 #include "GlowIconObject.h"
47 //----------------------------------------------------------------------------
49 #define max(a,b) ((a) > (b) ? (a) : (b))
50 #define min(a,b) ((a) < (b) ? (a) : (b))
53 #define NO_ICON_POSITION_WORD ((WORD) 0x8000)
55 //----------------------------------------------------------------------------
57 struct ExecBase *SysBase;
58 struct GfxBase *GfxBase;
59 T_UTILITYBASE UtilityBase;
60 struct Library *WorkbenchBase;
61 struct Library *IconBase;
62 struct Library *IconObjectDTBase;
63 struct IntuitionBase *IntuitionBase;
64 struct Library *CyberGfxBase;
65 struct Library *IFFParseBase;
66 struct DosLibrary *DOSBase;
67 #ifdef TIMESTAMPS
68 T_TIMERBASE TimerBase;
69 #endif /* TIMESTAMPS */
70 #ifdef __amigaos4__
71 struct Library *NewlibBase;
73 struct Interface *INewlib;
74 struct ExecIFace *IExec;
75 struct GraphicsIFace *IGraphics;
76 struct UtilityIFace *IUtility;
77 struct WorkbenchIFace *IWorkbench;
78 struct IconIFace *IIcon;
79 struct IntuitionIFace *IIntuition;
80 struct CyberGfxIFace *ICyberGfx;
81 struct IFFParseIFace *IIFFParse;
82 struct DOSIFace *IDOS;
83 #endif /* __amigaos4__ */
85 static void *MemPool;
86 static struct SignalSemaphore PubMemPoolSemaphore;
88 static Class *GlowIconObjectClass;
90 //----------------------------------------------------------------------------
91 // Standard library functions
93 static SAVEDS(ULONG) INTERRUPT GlowIconObjectDispatcher(Class *cl, Object *o, Msg msg);
95 //-----------------------------------------------------------------------------
97 static BOOL DtNew(Class *cl, Object *o, struct opSet *ops);
98 static ULONG DtDispose(Class *cl, Object *o, Msg msg);
99 static ULONG DtSet(Class *cl, Object *o, struct opSet *ops);
100 static ULONG DtGet(Class *cl, Object *o, struct opGet *opg);
101 static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl);
102 static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf);
103 static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *iopw);
104 static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *iopw);
105 static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio);
107 //----------------------------------------------------------------------------
109 static void FreePenList(struct Screen *screen, struct NewImagePenList *PenList);
110 static BOOL DoClonePenList(struct Screen *scr, struct NewImagePenList *nipDest,
111 const struct NewImagePenList *nipSrc);
112 static struct Image *DoCloneDoImage(struct Image *imgDest, const struct Image *imgSrc);
113 static void DoUpdateWb(CONST_STRPTR SavePath);
114 static void INLINE WriteARGBArray(const struct ARGB *SrcImgData,
115 ULONG SrcX, ULONG SrcY, ULONG SrcBytesPerRow,
116 struct RastPort *DestRp, ULONG DestX, ULONG DestY,
117 ULONG SizeX, ULONG SizeY);
118 static BOOL INLINE DrawTrueColorImage(struct RastPort *rp, struct NewImage *img,
119 UWORD Left, UWORD Top, const struct ColorRegister *Palette,
120 BOOL DimmedImage);
121 static BOOL INLINE DrawRemappedImage(struct InstanceData *inst, struct RastPort *rp,
122 struct NewImagePenList *PenList, struct NewImage *img,
123 UWORD Left, UWORD Top, const struct ColorRegister *Palette, ULONG PaletteSize,
124 BOOL DimmedImage);
125 static void DrawColorImage(struct InstanceData *inst, struct RastPort *rp,
126 struct NewImagePenList *PenList, struct NewImage *img,
127 UWORD Left, UWORD Top, const struct ColorRegister *Palette, ULONG PaletteSize,
128 BOOL DimmedImage);
129 static void ReadIcon(struct InstanceData *inst, CONST_STRPTR Filename, BPTR IconFh);
130 static BOOL WriteIcon(Class *cl, Object *o,
131 const struct DiskObject *WriteDiskObject, CONST_STRPTR Filename);
132 static BOOL ReadStandardIcon(struct InstanceData *inst, BPTR fd);
133 static BOOL WriteStandardIcon(struct InstanceData *inst,
134 const struct DiskObject *WriteDiskObject, BPTR fd);
135 static struct NewImage *ReadNewImage(struct IFFHandle *iff, const struct FaceChunk *fc);
136 static struct NewImage *ReadARGBImage(struct IFFHandle *iff, const struct FaceChunk *fc);
137 static LONG WriteNewImage(struct IFFHandle *iff, const struct NewImage *ni);
138 static LONG WriteARGBImage(Class *cl, Object *o, struct IFFHandle *iff,
139 const struct NewImage *ni, ULONG ARGBImageTag);
140 static void FreeNewImage(struct NewImage **ni);
141 static BOOL CloneNewImage(struct NewImage **niClone, const struct NewImage *niSrc);
142 static UBYTE *EncodeData(ULONG Depth, UWORD *DestLength,
143 ULONG SrcLength, const UBYTE *SrcData);
144 static BOOL DecodeData(const UBYTE *src, UBYTE *dest, size_t SrcLength,
145 size_t DestLength, LONG BitsPerEntry);
146 static UBYTE INLINE GetNextDestByte(const UBYTE **src, size_t *SrcLength, short *srcBits,
147 UBYTE *srcByte, LONG BitsPerEntry);
148 static UBYTE *GenerateMask(struct NewImage *nim);
149 static struct NewImage *NewImageFromSAC(struct ScalosBitMapAndColor *sac);
150 static void GenerateNormalImageMask(Class *cl, Object *o);
151 static void GenerateSelectedImageMask(Class *cl, Object *o);
152 static struct NewImage *NewImageFromNormalImage(const struct InstanceData *inst, const struct NewImage *niNormal);
153 static SAVEDS(LONG) StreamHookDispatcher(struct Hook *hook, struct IFFHandle *iff, const struct IFFStreamCmd *cmd);
154 static void SetParentAttributes(Class *cl, Object *o);
156 #if defined(__AROS__)
157 static BOOL ReadConvertStandardIcon(BPTR fd, struct DiskObject *dobj);
158 static BOOL WriteConvertStandardIcon(BPTR fd, struct DiskObject *dobj);
159 static BOOL ReadConvertDrawerData(BPTR fd, struct DrawerData *drawer);
160 static BOOL WriteConvertDrawerData(BPTR fd, struct DrawerData *drawer);
161 static BOOL ReadConvertImage(BPTR fd, struct Image *img);
162 static BOOL WriteConvertImage(BPTR fd, struct Image *img);
163 #endif
165 //----------------------------------------------------------------------------
167 static APTR MyAllocVecPooled(size_t Size);
168 static void MyFreeVecPooled(APTR mem);
169 static void *ZLibAlloc(void *p, int items, int size);
170 static void ZLibFree(void *p, void *addr);
172 //----------------------------------------------------------------------------
174 char ALIGNED libName[] = "glowiconobject.datatype";
175 char ALIGNED libIdString[] = "$VER: glowiconobject.datatype "
176 STR(LIB_VERSION) "." STR(LIB_REVISION)
177 " (25 Jan 2008 22:31:59) "
178 COMPILER_STRING
179 " ©2004" CURRENTYEAR " The Scalos Team";
181 static struct Hook StreamHook =
183 { NULL, NULL },
184 HOOKFUNC_DEF(StreamHookDispatcher), // h_Entry + h_SubEntry
185 NULL, // h_Data
188 //----------------------------------------------------------------------------
190 LIBFUNC(ObtainInfoEngine, libbase, ULONG)
192 (void) libbase;
194 d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase));
196 return (ULONG) GlowIconObjectClass;
198 LIBFUNC_END
200 //-----------------------------------------------------------------------------
202 // return 0 if error occurred
203 ULONG InitDatatype(struct GlowIconObjectDtLibBase *dtLib)
205 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
207 dtLib->nib_Initialized = FALSE;
209 return 1;
212 // return 0 if error occurred
213 ULONG OpenDatatype(struct GlowIconObjectDtLibBase *dtLib)
215 d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt));
217 if (!dtLib->nib_Initialized)
219 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
221 dtLib->nib_Initialized = TRUE;
223 InitSemaphore(&PubMemPoolSemaphore);
225 DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 39);
226 d1(kprintf("%s/%s/%ld: DOSBase=%08lx\n", __FILE__, __FUNC__, __LINE__, DOSBase));
227 if (NULL == DOSBase)
228 return 0;
229 #ifdef __amigaos4__
230 IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL);
231 if (NULL == IDOS)
232 return 0;
233 #endif /* __amigaos4__ */
235 IFFParseBase = OpenLibrary("iffparse.library", 39);
236 d1(kprintf("%s/%s/%ld: IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IFFParseBase));
237 if (NULL == IFFParseBase)
238 return 0;
239 #ifdef __amigaos4__
240 IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL);
241 if (NULL == IIFFParse)
242 return 0;
243 #endif /* __amigaos4__ */
245 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39);
246 d1(kprintf("%s/%s/%ld: IntuitionBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IntuitionBase));
247 if (NULL == IntuitionBase)
248 return 0;
249 #ifdef __amigaos4__
250 IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL);
251 if (NULL == IIntuition)
252 return 0;
253 #endif /* __amigaos4__ */
255 UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39);
256 d1(kprintf("%s/%s/%ld: UtilityBase=%08lx\n", __FILE__, __FUNC__, __LINE__, UtilityBase));
257 if (NULL == UtilityBase)
258 return 0;
259 #ifdef __amigaos4__
260 IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL);
261 if (NULL == IUtility)
262 return 0;
263 #endif /* __amigaos4__ */
265 IconBase = OpenLibrary(ICONNAME, 39);
266 d1(kprintf("%s/%s/%ld: IconBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IconBase));
267 if (NULL == IconBase)
268 return 0;
269 #ifdef __amigaos4__
270 IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL);
271 if (NULL == IIcon)
272 return 0;
273 #endif /* __amigaos4__ */
275 GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39);
276 d1(kprintf("%s/%s/%ld: GfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, GfxBase));
277 if (NULL == GfxBase)
278 return 0;
279 #ifdef __amigaos4__
280 IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL);
281 if (NULL == IGraphics)
282 return 0;
283 #endif /* __amigaos4__ */
285 WorkbenchBase = OpenLibrary("workbench.library", 39);
286 d1(KPrintF("%s/%s/%ld: WorkbenchBase=%08lx\n", __FILE__, __FUNC__, __LINE__, WorkbenchBase));
287 if (NULL == WorkbenchBase)
288 return 0;
289 #ifdef __amigaos4__
290 IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL);
291 if (NULL == IWorkbench)
292 return 0;
293 #endif /* __amigaos4__ */
295 IconObjectDTBase = OpenLibrary("datatypes/iconobject.datatype", 39);
296 if (NULL == IconObjectDTBase)
297 return 0;
299 #ifdef TIMESTAMPS
301 struct timerequest *iorequest;
303 iorequest = (struct timerequest *) CreateIORequest(CreateMsgPort(), sizeof(struct timerequest));
304 OpenDevice("timer.device", UNIT_VBLANK, &iorequest->tr_node, 0);
305 TimerBase = (T_TIMERBASE) iorequest->tr_node.io_Device;
307 #endif /* TIMESTAMPS */
309 #if !defined(__amigaos4__) && !defined(__AROS__)
310 if (_STI_240_InitMemFunctions())
311 return 0;
312 #endif /* __amigaos4__ */
314 MemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE);
315 d1(kprintf("%s/%s/%ld: MemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool));
316 if (NULL == MemPool)
317 return 0;
319 GlowIconObjectClass = dtLib->nib_ClassLibrary.cl_Class = MakeClass(libName,
320 "iconobject.datatype", NULL, sizeof(struct InstanceData), 0);
321 d1(kprintf("%s/%s/%ld: GlowIconObjectClass=%08lx\n", __FILE__, __FUNC__, __LINE__, GlowIconObjectClass));
322 if (NULL == GlowIconObjectClass)
323 return 0;
325 SETHOOKFUNC(GlowIconObjectClass->cl_Dispatcher, GlowIconObjectDispatcher);
326 GlowIconObjectClass->cl_Dispatcher.h_Data = dtLib;
328 // Make class available for the public
329 AddClass(GlowIconObjectClass);
331 CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0);
332 // CyberGfxBase may be NULL
333 #ifdef __amigaos4__
334 if (NULL != CyberGfxBase)
336 ICyberGfx = (struct CyberGfxIFace *)GetInterface((struct Library *)CyberGfxBase, "main", 1, NULL);
337 if (NULL == ICyberGfx)
339 CloseLibrary(CyberGfxBase);
340 CyberGfxBase = NULL;
343 NewlibBase = OpenLibrary("newlib.library", 0);
344 if (NULL == NewlibBase)
345 return 0;
346 INewlib = GetInterface(NewlibBase, "main", 1, NULL);
347 if (NULL == INewlib)
348 return 0;
349 #endif /* __amigaos4__ */
352 d1(kprintf("%s/%s/%ld: Open Success!\n", __FILE__, __FUNC__, __LINE__));
354 return 1;
357 void CloseDatatype(struct GlowIconObjectDtLibBase *dtLib)
359 d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt));
361 if (dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt < 1)
363 if (GlowIconObjectClass)
365 RemoveClass(GlowIconObjectClass);
366 FreeClass(GlowIconObjectClass);
367 GlowIconObjectClass = dtLib->nib_ClassLibrary.cl_Class = NULL;
370 if (NULL != IconObjectDTBase)
372 CloseLibrary(IconObjectDTBase);
373 IconObjectDTBase = NULL;
375 #ifdef __amigaos4__
376 if (INewlib)
378 DropInterface(INewlib);
379 INewlib = NULL;
381 if (NewlibBase)
383 CloseLibrary(NewlibBase);
384 NewlibBase = NULL;
386 if (NULL != IWorkbench)
388 DropInterface((struct Interface *)IWorkbench);
389 IWorkbench = NULL;
391 #endif /* __amigaos4__ */
392 if (NULL != WorkbenchBase)
394 CloseLibrary(WorkbenchBase);
395 WorkbenchBase = NULL;
397 #ifdef __amigaos4__
398 if (NULL != IIcon)
400 DropInterface((struct Interface *)IIcon);
401 IIcon = NULL;
403 #endif /* __amigaos4__ */
404 if (NULL != IconBase)
406 CloseLibrary(IconBase);
407 IconBase = NULL;
409 #ifdef __amigaos4__
410 if (NULL != ICyberGfx)
412 DropInterface((struct Interface *)ICyberGfx);
413 ICyberGfx = NULL;
415 #endif /* __amigaos4__ */
416 if (NULL != CyberGfxBase)
418 CloseLibrary(CyberGfxBase);
419 CyberGfxBase = NULL;
421 #if !defined(__amigaos4__) && !defined(__AROS__)
422 _STD_240_TerminateMemFunctions();
423 #endif /* __amigaos4__ */
424 if (NULL != MemPool)
426 DeletePool(MemPool);
427 MemPool = NULL;
430 #ifdef __amigaos4__
431 if (NULL != IGraphics)
433 DropInterface((struct Interface *)IGraphics);
434 IGraphics = NULL;
436 #endif /* __amigaos4__ */
437 if (NULL != GfxBase)
439 CloseLibrary((struct Library *) GfxBase);
440 GfxBase = NULL;
442 #ifdef __amigaos4__
443 if (NULL != IIntuition)
445 DropInterface((struct Interface *)IIntuition);
446 IIntuition = NULL;
448 #endif /* __amigaos4__ */
449 if (NULL != IntuitionBase)
451 CloseLibrary((struct Library *) IntuitionBase);
452 IntuitionBase = NULL;
454 #ifdef __amigaos4__
455 if (NULL != IIFFParse)
457 DropInterface((struct Interface *)IIFFParse);
458 IIFFParse = NULL;
460 #endif /* __amigaos4__ */
461 if (IFFParseBase)
463 CloseLibrary(IFFParseBase);
464 IFFParseBase = NULL;
466 #ifdef __amigaos4__
467 if (NULL != IUtility)
469 DropInterface((struct Interface *)IUtility);
470 IUtility = NULL;
472 #endif /* __amigaos4__ */
473 if (NULL != UtilityBase)
475 CloseLibrary((struct Library *) UtilityBase);
476 UtilityBase = NULL;
478 #ifdef __amigaos4__
479 if (NULL != IDOS)
481 DropInterface((struct Interface *)IDOS);
482 IDOS = NULL;
484 #endif /* __amigaos4__ */
485 if (NULL != DOSBase)
487 CloseLibrary((struct Library *)DOSBase);
488 DOSBase = NULL;
493 //-----------------------------------------------------------------------------
495 static SAVEDS(ULONG) INTERRUPT GlowIconObjectDispatcher(Class *cl, Object *o, Msg msg)
497 ULONG Result;
499 d1(kprintf("%s/%s/%ld: MethodID=%08lx o=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID, o));
501 switch (msg->MethodID)
503 case OM_NEW:
504 o = (Object *) DoSuperMethodA(cl, o, msg);
505 d1(kprintf("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
506 if (o)
508 d1(kprintf("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
509 if (!DtNew(cl, o, (struct opSet *) msg))
511 DoMethod(o, OM_DISPOSE);
512 o = NULL;
515 Result = (ULONG) o;
516 break;
518 case OM_DISPOSE:
519 d1(kprintf("%s/%s/%ld: OM_DISPOSE o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
520 Result = DtDispose(cl, o, msg);
521 break;
523 case OM_SET:
524 Result = DtSet(cl, o, (struct opSet *) msg);
525 break;
527 case OM_GET:
528 Result = DtGet(cl, o, (struct opGet *) msg);
529 break;
531 case IDTM_Layout:
532 Result = DtLayout(cl, o, (struct iopLayout *) msg);
533 break;
535 case IDTM_FreeLayout:
536 d1(kprintf("%s/%s/%ld: IDTM_FreeLayout o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
537 Result = DtFreeLayout(cl, o, (struct iopFreeLayout *) msg);
538 break;
540 case IDTM_Write:
541 Result = DtWrite(cl, o, (struct iopWrite *) msg);
542 break;
544 case IDTM_NewImage:
545 Result = DtNewImage(cl, o, (struct iopNewImage *) msg);
546 break;
548 case IDTM_CloneIconObject:
549 Result = DtClone(cl, o, (struct iopCloneIconObject *) msg);
550 break;
552 default:
553 d1(kprintf("%s/%s/%ld: default o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
554 Result = DoSuperMethodA(cl, o, msg);
555 break;
558 d1(kprintf("%s/%s/%ld: MethodID=%08lx o=%08lx Result=%ld\n", __FILE__, __FUNC__, __LINE__,
559 msg->MethodID, o, Result));
561 return Result;
564 //-----------------------------------------------------------------------------
566 static BOOL DtNew(Class *cl, Object *o, struct opSet *ops)
568 struct InstanceData *inst = INST_DATA(cl, o);
569 struct ExtGadget *gg = (struct ExtGadget *) o;
570 BOOL Success = FALSE;
572 do {
573 ULONG DefIconType;
574 STRPTR IconName;
575 ULONG SupportedIconTypes;
576 BPTR IconFh;
578 d1(kprintf("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
579 TIMESTAMP_d1();
581 memset(inst, 0, sizeof(struct InstanceData));
583 inst->aio_BackfillPenNorm = inst->aio_BackfillPenSel = IDTA_BACKFILL_NONE;
585 SupportedIconTypes = GetTagData(IDTA_SupportedIconTypes, ~0, ops->ops_AttrList);
586 if (!(SupportedIconTypes & IDTV_IconType_ColorIcon))
587 break;
589 inst->aio_ImageLeft = GetTagData(IDTA_InnerLeft, 0, ops->ops_AttrList);
590 inst->aio_ImageTop = GetTagData(IDTA_InnerTop, 0, ops->ops_AttrList);
592 DefIconType = GetTagData(IDTA_DefType, 0, ops->ops_AttrList);
593 d1(kprintf("%s/%s/%ld: o=%08lx DefIconType=%lu\n", __FILE__, __FUNC__, __LINE__, o, DefIconType));
595 if (0 != DefIconType)
596 break;
598 if (NULL != (struct DiskObject *) GetTagData(AIDTA_Icon, (ULONG) NULL, ops->ops_AttrList))
599 break;
601 if (FindTagItem(IDTA_CloneIconObject, ops->ops_AttrList))
603 d1(KPrintF("%s/%s/%ld: IDTA_CloneIconObject\n", __FILE__, __FUNC__, __LINE__));
605 else
607 GetAttr(DTA_Name, o, (APTR) &IconName);
608 d1(KPrintF("%s/%s/%ld: o=%08lx IconName=<%s>\n", __FILE__, __FUNC__, __LINE__, o, IconName ? IconName : (STRPTR) ""));
610 // Get named icon
611 if (NULL == IconName)
612 break;
614 IconFh = (BPTR)GetTagData(DTA_Handle, 0, ops->ops_AttrList);
615 d1(KPrintF("%s/%s/%ld: IconFh=%08lx\n", __FILE__, __FUNC__, __LINE__, IconFh));
617 TIMESTAMP_d1();
618 ReadIcon(inst, IconName, IconFh);
619 TIMESTAMP_d1();
620 if (NULL == inst->aio_Image1)
621 break; // fall back to standard icon if no NewImage
623 if (NULL == inst->aio_Image2)
625 // No selected image available.
626 // Generate darkened selected image from normal image
627 struct NewImage *ni;
629 TIMESTAMP_d1();
630 ni = NewImageFromNormalImage(inst, inst->aio_Image1);
631 d1(KPrintF("%s/%s/%ld: ni=%08lx\n", __FILE__, __FUNC__, __LINE__, ni));
632 if (NULL == ni)
633 break;
635 FreeNewImage(&inst->aio_Image2);
636 inst->aio_Image2 = ni;
639 d1(kprintf("%s/%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_DiskObject));
640 if (NULL == inst->aio_DiskObject)
641 break;
643 if (NO_ICON_POSITION == inst->aio_DiskObject->do_CurrentX)
645 gg->LeftEdge = gg->TopEdge = NO_ICON_POSITION_WORD;
647 else
649 gg->LeftEdge = inst->aio_DiskObject->do_CurrentX;
650 gg->TopEdge = inst->aio_DiskObject->do_CurrentY;
653 if (NULL == inst->aio_DiskObject->do_DrawerData)
655 inst->aio_myDrawerData = MyAllocVecPooled(sizeof(struct DrawerData));
656 if (NULL == inst->aio_myDrawerData)
657 break;
659 memset(inst->aio_myDrawerData, 0, sizeof(struct DrawerData));
661 switch (inst->aio_DiskObject->do_Type)
663 case WBTOOL:
664 case WBPROJECT:
665 case WBKICK:
666 break;
667 default:
668 inst->aio_DiskObject->do_DrawerData = inst->aio_myDrawerData;
669 break;
673 SetParentAttributes(cl, o);
674 TIMESTAMP_d1();
677 d1(kprintf("%s/%s/%ld: o=%08lx GadgetRender=%08lx\n", __FILE__, __FUNC__, __LINE__, o, gg->GadgetRender));
678 TIMESTAMP_d1();
680 Success = TRUE;
681 } while (0);
683 d1(kprintf("%s/%s/%ld: END o=%08lx Success=%ld\n", __FILE__, __FUNC__, __LINE__, o, Success));
684 TIMESTAMP_d1();
686 return Success;
689 //-----------------------------------------------------------------------------
691 static ULONG DtDispose(Class *cl, Object *o, Msg msg)
693 struct InstanceData *inst = INST_DATA(cl, o);
694 // struct ExtGadget *gg = (struct ExtGadget *) o;
696 d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
698 d1(kprintf("%s/%s/%ld: o=%08lx aio_myDrawerData=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_myDrawerData));
699 if (inst->aio_myDrawerData)
701 MyFreeVecPooled(inst->aio_myDrawerData);
702 inst->aio_myDrawerData = NULL;
703 if (inst->aio_DiskObject)
704 inst->aio_DiskObject->do_DrawerData = NULL;
707 if (inst->aio_DefaultTool)
709 MyFreeVecPooled(inst->aio_DefaultTool);
710 inst->aio_DefaultTool = NULL;
712 if (inst->aio_ToolTypes)
714 STRPTR *ToolTypePtr = inst->aio_ToolTypes;
716 d1(KPrintF("%s/%s/%ld: do_ToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_ToolTypes));
718 while (*ToolTypePtr)
720 d1(KPrintF("%s/%s/%ld: *ToolTypePtr=<%s>\n", __FILE__, __FUNC__, __LINE__, *ToolTypePtr));
721 MyFreeVecPooled(*ToolTypePtr);
722 *ToolTypePtr = NULL;
723 ToolTypePtr++;
726 MyFreeVecPooled(inst->aio_ToolTypes);
727 inst->aio_ToolTypes = NULL;
729 if (inst->aio_ToolWindow)
731 MyFreeVecPooled(inst->aio_ToolWindow);
732 inst->aio_ToolWindow = NULL;
735 d1(kprintf("%s/%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_DiskObject));
737 if (inst->aio_DiskObject)
739 MyFreeVecPooled(inst->aio_DiskObject);
740 inst->aio_DiskObject = NULL;
742 if (inst->aio_DoImage1.ImageData)
744 MyFreeVecPooled(inst->aio_DoImage1.ImageData);
745 inst->aio_DoImage1.ImageData = NULL;
747 if (inst->aio_DoImage2.ImageData)
749 MyFreeVecPooled(inst->aio_DoImage2.ImageData);
750 inst->aio_DoImage2.ImageData = NULL;
752 if (inst->aio_PenList1.nip_PenArray)
754 FreePenList(inst->aio_Screen, &inst->aio_PenList1);
756 if (inst->aio_PenList2.nip_PenArray)
758 FreePenList(inst->aio_Screen, &inst->aio_PenList2);
761 FreeNewImage(&inst->aio_Image1);
762 FreeNewImage(&inst->aio_Image2);
764 d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
766 return DoSuperMethodA(cl, o, msg);
769 //----------------------------------------------------------------------------------------
771 static ULONG DtSet(Class *cl, Object *o, struct opSet *ops)
773 struct InstanceData *inst = INST_DATA(cl, o);
775 d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
777 inst->aio_ImageLeft = GetTagData(IDTA_InnerLeft, inst->aio_ImageLeft, ops->ops_AttrList);
778 inst->aio_ImageTop = GetTagData(IDTA_InnerTop, inst->aio_ImageTop, ops->ops_AttrList);
780 inst->aio_BackfillPenNorm = GetTagData(IDTA_Backfill, inst->aio_BackfillPenNorm, ops->ops_AttrList);
781 inst->aio_BackfillPenSel = GetTagData(IDTA_BackfillSel, inst->aio_BackfillPenSel, ops->ops_AttrList);
783 return DoSuperMethodA(cl, o, (Msg) ops);
786 //----------------------------------------------------------------------------------------
788 static ULONG DtGet(Class *cl, Object *o, struct opGet *opg)
790 struct InstanceData *inst = INST_DATA(cl, o);
791 ULONG result = 1;
793 d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
795 switch (opg->opg_AttrID)
797 case IDTA_IconType:
798 *opg->opg_Storage = ioICONTYPE_GlowIcon;
799 break;
801 case IDTA_NumberOfColorsSupported:
802 *opg->opg_Storage = inst->aio_Image1->nim_Palette ? 256 : (1 + 0x00ffffff);
803 d1(KPrintF("%s/%s/%ld: o=%08lx IDTA_NumberOfColorsSupported=%lu\n", __FILE__, __FUNC__, __LINE__, o, *opg->opg_Storage));
804 break;
806 case AIDTA_Icon:
807 *opg->opg_Storage = (ULONG) inst->aio_DiskObject;
808 break;
810 case IDTA_Extention:
811 *opg->opg_Storage = (ULONG) ".info";
812 break;
814 default:
815 result = DoSuperMethodA(cl, o, (Msg) opg);
816 break;
819 d1(kprintf("%s/%s/%ld: o=%08lx GadgetRender=%08lx\n", __FILE__, __FUNC__, __LINE__, o, ((struct ExtGadget *) o)->GadgetRender));
821 return result;
824 //-----------------------------------------------------------------------------
826 static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl)
828 struct InstanceData *inst = INST_DATA(cl, o);
829 struct ExtGadget *gg = (struct ExtGadget *) o;
831 d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
833 TIMESTAMP_d1();
834 DoSuperMethodA(cl, o, (Msg) iopl);
835 TIMESTAMP_d1();
837 d1(kprintf("%s/%s/%ld: o=%08lx Screen=%08lx\n", __FILE__, __FUNC__, __LINE__, o, iopl->iopl_Screen));
838 d1(KPrintF("%s/%s/%ld: o=%08lx Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, o, gg->Width, gg->Height));
839 d1(kprintf("%s/%s/%ld: o=%08lx GadgetRender=%08lx SelectRender=%08lx Flags=%08lx\n", \
840 __FILE__, __FUNC__, __LINE__, o, gg->GadgetRender, gg->SelectRender, iopl->iopl_Flags));
842 // skip layout if ARGB image (no nim_Palette)
843 if (inst->aio_Image1->nim_Palette)
845 inst->aio_Screen = iopl->iopl_Screen;
847 if (gg->GadgetRender && (iopl->iopl_Flags & IOLAYOUTF_NormalImage))
849 d1(KPrintF("%s/%s/%ld: o=%08lx Image1 nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_Image1->nim_Palette));
850 if (inst->aio_Image1->nim_Palette)
852 TIMESTAMP_d1();
853 DrawColorImage(inst, (struct RastPort *) gg->GadgetRender,
854 &inst->aio_PenList1, inst->aio_Image1,
855 inst->aio_ImageLeft, inst->aio_ImageTop,
856 inst->aio_Image1->nim_Palette, inst->aio_Image1->nim_PaletteSize,
857 FALSE);
858 TIMESTAMP_d1();
861 if (gg->SelectRender && (iopl->iopl_Flags & IOLAYOUTF_SelectedImage))
863 BOOL DimImage;
864 const struct ColorRegister *Palette;
865 ULONG PaletteSize;
866 struct NewImage *nim;
868 d1(KPrintF("%s/%s/%ld: o=%08lx Image2=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_Image2));
869 TIMESTAMP_d1();
871 if (inst->aio_Image2)
873 nim = inst->aio_Image2;
875 if (inst->aio_Image2->nim_ImageChunk.ic_Flags & ICF_HasPalette)
877 Palette = inst->aio_Image2->nim_Palette;
878 PaletteSize = inst->aio_Image2->nim_PaletteSize;
880 else
882 Palette = inst->aio_Image1->nim_Palette;
883 PaletteSize = inst->aio_Image1->nim_PaletteSize;
885 DimImage = FALSE;
887 else
889 nim = inst->aio_Image1;
890 Palette = inst->aio_Image1->nim_Palette;
891 PaletteSize = inst->aio_Image1->nim_PaletteSize;
892 DimImage = TRUE;
895 d1(KPrintF("%s/%s/%ld: o=%08lx Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_Image1->nim_Palette));
896 DrawColorImage(inst, (struct RastPort *) gg->SelectRender,
897 &inst->aio_PenList2, nim,
898 inst->aio_ImageLeft, inst->aio_ImageTop,
899 Palette, PaletteSize, DimImage);
903 d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
904 TIMESTAMP_d1();
906 return 0;
909 //-----------------------------------------------------------------------------
911 static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf)
913 struct InstanceData *inst = INST_DATA(cl, o);
914 // struct ExtGadget *gg = (struct ExtGadget *) o;
916 d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
918 if (inst->aio_Screen && (opf->iopf_Flags & IOFREELAYOUTF_ScreenAvailable))
920 if (inst->aio_PenList1.nip_PenArray)
922 FreePenList(inst->aio_Screen, &inst->aio_PenList1);
924 if (inst->aio_PenList2.nip_PenArray)
926 FreePenList(inst->aio_Screen, &inst->aio_PenList2);
929 else
931 if (inst->aio_PenList1.nip_PenArray)
933 MyFreeVecPooled(inst->aio_PenList1.nip_PenArray);
934 inst->aio_PenList1.nip_PenArray = NULL;
936 if (inst->aio_PenList2.nip_PenArray)
938 MyFreeVecPooled(inst->aio_PenList2.nip_PenArray);
939 inst->aio_PenList2.nip_PenArray = NULL;
943 d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
945 return DoSuperMethodA(cl, o, (Msg) opf);
948 //-----------------------------------------------------------------------------
950 static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *iopw)
952 struct InstanceData *inst = INST_DATA(cl, o);
953 struct ExtGadget *gg = (struct ExtGadget *) o;
954 struct WriteData wd;
955 struct DiskObject *WriteDiskObject;
956 struct DiskObject DiskObjectCopy;
957 ULONG Result = RETURN_OK;
959 d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
961 do {
962 ULONG NeedUpdateWB;
963 IPTR storage;
965 memset(&DiskObjectCopy, 0, sizeof(DiskObjectCopy));
967 NeedUpdateWB = GetTagData(ICONA_NotifyWorkbench, FALSE, iopw->iopw_Tags);
969 // Allocate empty DiskObject
970 WriteDiskObject = GetDiskObjectNew(NULL);
971 d1(kprintf("%s/%s/%ld: o=%08lx WriteDiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, o, WriteDiskObject));
972 if (NULL == WriteDiskObject)
973 break;
975 // Remember original contents of WriteDiskObject
976 DiskObjectCopy = *WriteDiskObject;
978 memset(&wd, 0, sizeof(wd));
980 GetAttr(IDTA_Type, o, &storage);
981 wd.aiowd_Type = storage;
982 GetAttr(IDTA_ViewModes, o, &storage);
983 wd.aiowd_ViewModes = storage;
984 GetAttr(IDTA_Flags, o, &storage);
985 wd.aiowd_Flags = storage;
986 GetAttr(IDTA_WinCurrentX, o, &storage);
987 wd.aiowd_CurrentX = storage;
988 GetAttr(IDTA_WinCurrentY, o, &storage);
989 wd.aiowd_CurrentY = storage;
990 GetAttr(IDTA_WindowRect, o, &storage);
991 wd.aiowd_WindowRect = (struct IBox *)storage;
992 GetAttr(IDTA_Stacksize, o, &storage);
993 wd.aiowd_StackSize = storage;
994 GetAttr(IDTA_ToolTypes, o, &storage);
995 wd.aiowd_ToolTypes = (STRPTR *)storage;
996 GetAttr(IDTA_DefaultTool, o, &storage);
997 wd.aiowd_DefaultTool = (STRPTR)storage;
999 *WriteDiskObject = *inst->aio_DiskObject;
1001 WriteDiskObject->do_DefaultTool = wd.aiowd_DefaultTool;
1002 WriteDiskObject->do_ToolTypes = wd.aiowd_ToolTypes;
1003 WriteDiskObject->do_StackSize = wd.aiowd_StackSize;
1004 WriteDiskObject->do_Type = wd.aiowd_Type;
1005 WriteDiskObject->do_DrawerData = NULL;
1006 WriteDiskObject->do_Gadget = inst->aio_DiskObject->do_Gadget;
1007 WriteDiskObject->do_ToolWindow = inst->aio_DiskObject->do_ToolWindow;
1009 switch (WriteDiskObject->do_Type)
1011 case WBTOOL:
1012 case WBPROJECT:
1013 case WBKICK:
1014 break;
1015 default:
1016 if (inst->aio_DiskObject->do_DrawerData)
1017 WriteDiskObject->do_DrawerData = inst->aio_DiskObject->do_DrawerData;
1018 else
1019 WriteDiskObject->do_DrawerData = inst->aio_myDrawerData;
1021 WriteDiskObject->do_DrawerData->dd_CurrentX = wd.aiowd_CurrentX;
1022 WriteDiskObject->do_DrawerData->dd_CurrentY = wd.aiowd_CurrentY;
1024 if (wd.aiowd_WindowRect)
1026 WriteDiskObject->do_DrawerData->dd_NewWindow.LeftEdge = wd.aiowd_WindowRect->Left;
1027 WriteDiskObject->do_DrawerData->dd_NewWindow.TopEdge = wd.aiowd_WindowRect->Top;
1028 WriteDiskObject->do_DrawerData->dd_NewWindow.Width = wd.aiowd_WindowRect->Width;
1029 WriteDiskObject->do_DrawerData->dd_NewWindow.Height = wd.aiowd_WindowRect->Height;
1030 WriteDiskObject->do_DrawerData->dd_Flags = wd.aiowd_Flags;
1031 WriteDiskObject->do_DrawerData->dd_ViewModes = wd.aiowd_ViewModes;
1033 break;
1036 if (GetTagData(ICONA_NoPosition, 0, iopw->iopw_Tags))
1038 WriteDiskObject->do_CurrentX = WriteDiskObject->do_CurrentY = NO_ICON_POSITION;
1040 else
1042 if (NO_ICON_POSITION_WORD == gg->LeftEdge)
1044 WriteDiskObject->do_CurrentX = WriteDiskObject->do_CurrentY = NO_ICON_POSITION;
1046 else
1048 WriteDiskObject->do_CurrentX = gg->LeftEdge;
1049 WriteDiskObject->do_CurrentY = gg->TopEdge;
1053 d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx Path=<%s>\n", __FILE__, __FUNC__, __LINE__, o, inst, iopw->iopw_Path));
1055 if (GetTagData(ICONA_NoNewImage, 0, iopw->iopw_Tags))
1059 if (NULL == inst->aio_Image1->nim_Palette)
1061 // Special check for ARGB icons:
1062 // if no IDTA_SelARGBImageData is present (e.g. for created Thumbnails),
1063 // then make sure inst->aio_Image2 is cleared.
1064 struct ARGBHeader *argbh = NULL;
1066 GetAttr(IDTA_SelARGBImageData, o, (APTR) &argbh);
1067 if (NULL == argbh || NULL == argbh->argb_ImageData)
1068 FreeNewImage(&inst->aio_Image2);
1071 if (!WriteIcon(cl, o, WriteDiskObject, iopw->iopw_Path))
1073 Result = IoErr();
1074 break;
1077 if (NeedUpdateWB)
1078 DoUpdateWb(iopw->iopw_Path);
1079 } while (0);
1081 if (WriteDiskObject)
1083 // Restore original contents of WriteDiskObject
1084 *WriteDiskObject = DiskObjectCopy;
1085 FreeDiskObject(WriteDiskObject);
1088 return Result;
1091 //-----------------------------------------------------------------------------
1093 static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *ioni)
1095 struct InstanceData *inst = INST_DATA(cl, o);
1097 d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1099 do {
1100 struct NewImage *ni;
1102 if (NULL == ioni->ioni_NormalImage)
1103 break;
1105 ni = NewImageFromSAC(ioni->ioni_NormalImage);
1106 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, ni));
1107 if (NULL == ni)
1108 break;
1110 if (inst->aio_PenList1.nip_PenArray)
1112 FreePenList(inst->aio_Screen, &inst->aio_PenList1);
1115 FreeNewImage(&inst->aio_Image1);
1116 inst->aio_Image1 = ni;
1118 if (ioni->ioni_SelectedImage)
1120 ni = NewImageFromSAC(ioni->ioni_SelectedImage);
1121 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, ni));
1122 if (NULL == ni)
1123 break;
1125 else
1127 ni = NewImageFromNormalImage(inst, inst->aio_Image1);
1128 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, ni));
1129 if (NULL == ni)
1130 break;
1133 if (inst->aio_PenList2.nip_PenArray)
1135 FreePenList(inst->aio_Screen, &inst->aio_PenList2);
1138 FreeNewImage(&inst->aio_Image2);
1139 inst->aio_Image2 = ni;
1140 } while (0);
1142 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1144 // update aio_FaceChunk
1145 inst->aio_FaceChunk.fc_Width = inst->aio_Image1->nim_Width;
1146 inst->aio_FaceChunk.fc_Height = inst->aio_Image1->nim_Height;
1147 if (inst->aio_Image2)
1149 if (inst->aio_Image2->nim_Width > inst->aio_Image1->nim_Width)
1150 inst->aio_FaceChunk.fc_Width = inst->aio_Image2->nim_Width;
1151 if (inst->aio_Image2->nim_Height > inst->aio_Image1->nim_Height)
1152 inst->aio_FaceChunk.fc_Height = inst->aio_Image2->nim_Height;
1154 inst->aio_FaceChunk.fc_Width--;
1155 inst->aio_FaceChunk.fc_Height--;
1157 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1159 SetAttrs(o,
1160 GA_Width, inst->aio_Image1->nim_Width,
1161 GA_Height, inst->aio_Image1->nim_Height,
1162 IDTA_UnscaledWidth, inst->aio_Image1->nim_Width,
1163 IDTA_UnscaledHeight, inst->aio_Image1->nim_Height,
1164 TAG_END);
1166 GenerateNormalImageMask(cl, o);
1167 GenerateSelectedImageMask(cl, o);
1169 d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1171 return 0;
1174 //-----------------------------------------------------------------------------
1176 static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio)
1178 struct InstanceData *inst = INST_DATA(cl, o);
1179 Object *oClone;
1180 BOOL Success = FALSE;
1182 d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1184 do {
1185 struct ExtGadget *gg = (struct ExtGadget *) o;
1186 struct ARGBHeader *NrmARGBImage = &inst->aio_Image1->nim_ARGBheader;
1187 struct ARGBHeader *SelARGBImage = &inst->aio_Image2->nim_ARGBheader;
1188 struct InstanceData *instClone;
1190 oClone = (Object *) NewObject(cl, NULL,
1191 DTA_Name, "cloned", // REQUIRED, otherwise NewObject() will fail
1192 IDTA_CloneIconObject, o,
1193 TAG_MORE, iocio->iocio_TagList,
1194 TAG_END);
1195 d1(KPrintF("%s/%ld: o=%08lx inst=%08lx oClone=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, oClone));
1196 if (NULL == oClone)
1197 break;
1199 instClone = INST_DATA(cl, oClone);
1201 *instClone = *inst;
1203 if (inst->aio_myDrawerData)
1205 instClone->aio_myDrawerData = MyAllocVecPooled(sizeof(struct DrawerData));
1206 if (NULL == instClone->aio_myDrawerData)
1207 break;
1209 *(instClone->aio_myDrawerData) = *(inst->aio_myDrawerData);
1212 if (inst->aio_DefaultTool)
1214 // Clone Default Tool
1215 instClone->aio_DefaultTool = MyAllocVecPooled(1 + strlen(inst->aio_DefaultTool));
1216 d1(KPrintF("%s/%s/%ld: aio_DefaultTool=%08lx\n", __FILE__, __FUNC__, __LINE__, instClone->aio_DefaultTool));
1217 if (NULL == instClone->aio_DefaultTool)
1218 break;
1220 strcpy(instClone->aio_DefaultTool, inst->aio_DefaultTool);
1222 if (inst->aio_ToolWindow)
1224 // Clone Tool Window
1225 instClone->aio_ToolWindow = MyAllocVecPooled(1 + strlen(inst->aio_ToolWindow));
1226 d1(KPrintF("%s/%s/%ld: aio_ToolWindow=%08lx\n", __FILE__, __FUNC__, __LINE__, instClone->aio_ToolWindow));
1227 if (NULL == instClone->aio_ToolWindow)
1228 break;
1230 strcpy(instClone->aio_ToolWindow, inst->aio_ToolWindow);
1233 if (inst->aio_ToolTypes)
1235 // Clone ToolTypes array
1236 STRPTR *ToolTypeSrc = inst->aio_ToolTypes;
1237 STRPTR *ToolTypeDest;
1239 instClone->aio_ToolTypes = instClone->aio_DiskObject->do_ToolTypes = (STRPTR *) MyAllocVecPooled(inst->aio_ToolTypesLength);
1240 if (NULL == instClone->aio_DiskObject->do_ToolTypes)
1241 break;
1243 d1(KPrintF("%s/%s/%ld: do_ToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, instClone->aio_DiskObject->do_ToolTypes));
1245 ToolTypeDest = instClone->aio_ToolTypes;
1247 while (*ToolTypeSrc)
1249 d1(KPrintF("%s/%s/%ld: *ToolTypePtr=<%s>\n", __FILE__, __FUNC__, __LINE__, *ToolTypeSrc));
1250 *ToolTypeDest = MyAllocVecPooled(1 + strlen(*ToolTypeSrc));
1251 if (NULL == *ToolTypeDest)
1252 break;
1254 strcpy(*ToolTypeDest, *ToolTypeSrc);
1256 ToolTypeSrc++;
1257 ToolTypeDest++;
1259 *ToolTypeDest = NULL;
1261 if (inst->aio_DiskObject)
1263 // Clone DiskObject
1264 instClone->aio_DiskObject = MyAllocVecPooled(sizeof(struct DiskObject));
1265 d1(KPrintF("%s/%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, o, instClone->aio_DiskObject));
1266 if (NULL == instClone->aio_DiskObject)
1267 break;
1269 *(instClone->aio_DiskObject) = *(inst->aio_DiskObject);
1272 // Clone aio_DoImage1
1273 instClone->aio_DiskObject->do_Gadget.GadgetRender = DoCloneDoImage(&instClone->aio_DoImage1, &inst->aio_DoImage1);
1275 // Clone aio_DoImage2
1276 instClone->aio_DiskObject->do_Gadget.SelectRender = DoCloneDoImage(&instClone->aio_DoImage2, &inst->aio_DoImage2);
1278 // Clone Normal Image Pen list
1279 if (!DoClonePenList(inst->aio_Screen, &instClone->aio_PenList1, &inst->aio_PenList1))
1280 break;
1281 // Clone Selected Image Pen list
1282 if (!DoClonePenList(inst->aio_Screen, &instClone->aio_PenList2, &inst->aio_PenList2))
1283 break;
1285 if (!CloneNewImage(&instClone->aio_Image1, inst->aio_Image1))
1286 break;
1287 if (!CloneNewImage(&instClone->aio_Image2, inst->aio_Image2))
1288 break;
1290 SetAttrsA(oClone, iocio->iocio_TagList);
1292 SetParentAttributes(cl, oClone);
1294 d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height));
1296 d1(KPrintF("%s/%s/%ld: NrmARGBImage=%08lx argb_ImageData=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1297 NrmARGBImage, NrmARGBImage->argb_ImageData, NrmARGBImage->argb_Width, NrmARGBImage->argb_Height));
1298 d1(KPrintF("%s/%s/%ld: SelARGBImage=%08lx argb_ImageData=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1299 SelARGBImage, SelARGBImage->argb_ImageData, SelARGBImage->argb_Width, SelARGBImage->argb_Height));
1301 GetAttr(IDTA_ARGBImageData, o, (APTR) &NrmARGBImage);
1302 GetAttr(IDTA_SelARGBImageData, o, (APTR) &SelARGBImage);
1304 d1(KPrintF("%s/%s/%ld: NrmARGBImage=%08lx argb_ImageData=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1305 NrmARGBImage, NrmARGBImage->argb_ImageData, NrmARGBImage->argb_Width, NrmARGBImage->argb_Height));
1306 d1(KPrintF("%s/%s/%ld: SelARGBImage=%08lx argb_ImageData=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1307 SelARGBImage, SelARGBImage->argb_ImageData, SelARGBImage->argb_Width, SelARGBImage->argb_Height));
1309 // clone size of original icon
1310 SetAttrs(oClone,
1311 GA_Width, gg->Width,
1312 GA_Height, gg->Height,
1313 TAG_END);
1315 if (NrmARGBImage != &inst->aio_Image1->nim_ARGBheader
1316 && NrmARGBImage->argb_ImageData
1317 && NrmARGBImage->argb_Width > 0
1318 && NrmARGBImage->argb_Height )
1320 if ((NrmARGBImage->argb_Width > gg->Width) || (NrmARGBImage->argb_Height > gg->Height))
1322 SetAttrs(oClone,
1323 GA_Width, NrmARGBImage->argb_Width,
1324 GA_Height, NrmARGBImage->argb_Height,
1325 TAG_END);
1327 // IDTA_ARGBImageData has been changed, clone it now!
1328 SetAttrs(oClone,
1329 IDTA_CopyARGBImageData, TRUE,
1330 IDTA_ARGBImageData, (APTR) NrmARGBImage,
1331 TAG_END);
1334 d1(KPrintF("%s/%s/%ld: NrmARGBImage=%08lx nim_ARGBheader=%08lx\n", __FILE__, __FUNC__, __LINE__, &inst->aio_Image1->nim_ARGBheader));
1335 if (SelARGBImage != &inst->aio_Image2->nim_ARGBheader
1336 && SelARGBImage->argb_ImageData
1337 && SelARGBImage->argb_Width > 0
1338 && SelARGBImage->argb_Height )
1340 if ((SelARGBImage->argb_Width > gg->Width) || (SelARGBImage->argb_Height > gg->Height))
1342 SetAttrs(oClone,
1343 GA_Width, SelARGBImage->argb_Width,
1344 GA_Height, SelARGBImage->argb_Height,
1345 TAG_END);
1347 // IDTA_SelARGBImageData has been changed, clone it now!
1348 SetAttrs(oClone,
1349 IDTA_CopySelARGBImageData, TRUE,
1350 IDTA_SelARGBImageData, (APTR) SelARGBImage,
1351 TAG_END);
1354 Success = TRUE;
1355 } while (0);
1357 if (oClone && !Success)
1359 DoMethod(oClone, OM_DISPOSE);
1360 oClone = NULL;
1363 d1(KPrintF("%s/%ld: END o=%08lx inst=%08lx oClone=%08lx\n", __FUNC__, __LINE__, o, inst, oClone));
1365 return (ULONG) oClone;
1368 //-----------------------------------------------------------------------------
1370 static BOOL DoClonePenList(struct Screen *scr, struct NewImagePenList *nipDest,
1371 const struct NewImagePenList *nipSrc)
1373 BOOL Success = FALSE;
1375 if (nipSrc->nip_PenArray)
1377 do {
1378 const UBYTE *PenArraySrc = nipSrc->nip_PenArray;
1379 UBYTE *PenArrayDest;
1380 ULONG n;
1382 nipDest->nip_PenArray = MyAllocVecPooled(nipDest->nip_PaletteSize);
1383 if (NULL == nipDest->nip_PenArray)
1384 break;
1386 memcpy(nipDest->nip_PenArray, nipSrc->nip_PenArray, nipDest->nip_PaletteSize);
1388 PenArrayDest = nipDest->nip_PenArray;
1389 for (n = 0; n < nipDest->nip_PaletteSize; n++)
1391 *PenArrayDest++ = ObtainPen(scr->ViewPort.ColorMap,
1392 *PenArraySrc++,
1393 0, 0, 0,
1394 PEN_NO_SETCOLOR);
1397 Success = TRUE;
1398 } while (0);
1400 else
1402 Success = TRUE;
1405 return Success;
1408 //-----------------------------------------------------------------------------
1410 static struct Image *DoCloneDoImage(struct Image *imgDest, const struct Image *imgSrc)
1412 if (imgSrc->ImageData)
1414 do {
1415 size_t len = RASSIZE(imgDest->Width, imgDest->Height) * imgDest->Depth;
1417 imgDest->ImageData = MyAllocVecPooled(len);
1418 if (NULL == imgDest->ImageData)
1419 break;
1421 memcpy(imgDest->ImageData, imgSrc->ImageData, len);
1423 return imgDest;
1424 } while (0);
1427 return NULL;
1430 //-----------------------------------------------------------------------------
1432 static void DoUpdateWb(CONST_STRPTR SavePath)
1434 BPTR fLock;
1435 BPTR pLock = (BPTR)NULL;
1437 do {
1438 CONST_STRPTR fName;
1440 fLock = Lock(SavePath, ACCESS_READ);
1441 if ((BPTR)NULL == fLock)
1442 break;
1444 pLock = ParentDir(fLock);
1445 if ((BPTR)NULL == pLock)
1446 break;
1448 fName = FilePart(SavePath);
1450 UpdateWorkbench(fName, pLock, UPDATEWB_ObjectAdded);
1451 } while (0);
1453 if (pLock)
1454 UnLock(pLock);
1455 if (fLock)
1456 UnLock(fLock);
1459 //----------------------------------------------------------------------------------------
1461 static void FreePenList(struct Screen *screen, struct NewImagePenList *PenList)
1463 UBYTE *PenArray = PenList->nip_PenArray;
1465 while (PenList->nip_PaletteSize--)
1467 ReleasePen(screen->ViewPort.ColorMap, *PenArray++);
1470 MyFreeVecPooled(PenList->nip_PenArray);
1471 PenList->nip_PenArray = NULL;
1474 //----------------------------------------------------------------------------------------
1476 static void INLINE WriteARGBArray(const struct ARGB *SrcImgData,
1477 ULONG SrcX, ULONG SrcY, ULONG SrcBytesPerRow,
1478 struct RastPort *DestRp, ULONG DestX, ULONG DestY,
1479 ULONG SizeX, ULONG SizeY)
1481 struct BitMap *DestBM = DestRp->BitMap;
1482 ULONG DestWidth;
1483 ULONG DestHeight;
1485 DestWidth = GetCyberMapAttr(DestBM, CYBRMATTR_WIDTH);
1486 DestHeight = GetCyberMapAttr(DestBM, CYBRMATTR_HEIGHT);
1488 d1(KPrintF("%s/%s/%ld: DestX=%ld DestY=%ld SizeX=%ld SizeY=%ld\n", __FILE__, __FUNC__, __LINE__, DestX, DestY, SizeX, SizeY));
1490 if (DestX + SizeX > DestWidth)
1491 SizeX = DestWidth - DestX;
1492 if (DestY + SizeY > DestHeight)
1493 SizeY = DestHeight - DestY;
1495 d1(KPrintF("%s/%s/%ld: DestX=%ld DestY=%ld SizeX=%ld SizeY=%ld\n", __FILE__, __FUNC__, __LINE__, DestX, DestY, SizeX, SizeY));
1497 WritePixelArray((APTR) SrcImgData, SrcX, SrcY,
1498 SrcBytesPerRow,
1499 DestRp, DestX, DestY,
1500 SizeX, SizeY,
1501 RECTFMT_ARGB);
1504 //----------------------------------------------------------------------------------------
1506 // True color
1507 static BOOL INLINE DrawTrueColorImage(struct RastPort *rp, struct NewImage *img,
1508 UWORD Left, UWORD Top, const struct ColorRegister *Palette,
1509 BOOL DimmedImage)
1511 struct ARGB *ARGBImgArray;
1512 BOOL Success = FALSE;
1514 d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
1516 do {
1517 ULONG BmWidth, BmHeight;
1518 ULONG Width, Height;
1519 const struct ColorRegister *PalettePtr;
1520 size_t ARGBImgSize;
1521 struct ARGB *ARGBImgDestPtr;
1522 UBYTE *ImgSrcPtr;
1523 ULONG n;
1524 ULONG ImgSize;
1526 BmWidth = GetBitMapAttr(rp->BitMap, BMA_WIDTH);
1527 BmHeight = GetBitMapAttr(rp->BitMap, BMA_HEIGHT);
1529 Width = min(img->nim_Width, BmWidth - Left);
1530 Height = min(img->nim_Height, BmHeight - Top);
1532 ImgSize = img->nim_Width * img->nim_Height;
1533 ARGBImgSize = ImgSize * sizeof(struct ARGB);
1535 ARGBImgArray = MyAllocVecPooled(ARGBImgSize);
1536 d1(KPrintF("%s/%s/%ld: ARGBImgArray=%08lx\n", __FILE__, __FUNC__, __LINE__, ARGBImgArray));
1537 if (NULL == ARGBImgArray)
1538 break;
1540 ImgSrcPtr = img->nim_ImageData;
1541 ARGBImgDestPtr = ARGBImgArray;
1542 PalettePtr = Palette;
1544 if (DimmedImage)
1546 for (n = 0; n < ImgSize; n++, ARGBImgDestPtr++)
1548 const struct ColorRegister *PaletteEntry;
1550 PaletteEntry = &PalettePtr[*ImgSrcPtr++];
1551 ARGBImgDestPtr->Alpha = 0xff;
1552 ARGBImgDestPtr->Red = PaletteEntry->red / 2;
1553 ARGBImgDestPtr->Green = PaletteEntry->green / 2;
1554 ARGBImgDestPtr->Blue = PaletteEntry->blue / 2;
1557 else
1559 for (n = 0; n < ImgSize; n++, ARGBImgDestPtr++)
1561 const struct ColorRegister *PaletteEntry;
1563 PaletteEntry = &PalettePtr[*ImgSrcPtr++];
1564 ARGBImgDestPtr->Alpha = 0xff;
1565 ARGBImgDestPtr->Red = PaletteEntry->red;
1566 ARGBImgDestPtr->Green = PaletteEntry->green;
1567 ARGBImgDestPtr->Blue = PaletteEntry->blue;
1571 WriteARGBArray(ARGBImgArray, 0, 0,
1572 img->nim_Width * sizeof(struct ARGB),
1573 rp, Left, Top,
1574 Width, Height);
1576 Success = TRUE;
1577 } while (0);
1579 if (ARGBImgArray)
1580 MyFreeVecPooled(ARGBImgArray);
1582 return Success;
1585 //----------------------------------------------------------------------------------------
1587 static BOOL INLINE DrawRemappedImage(struct InstanceData *inst, struct RastPort *rp,
1588 struct NewImagePenList *PenList, struct NewImage *img,
1589 UWORD Left, UWORD Top, const struct ColorRegister *Palette, ULONG PaletteSize,
1590 BOOL DimmedImage)
1592 UBYTE *MappedImage = NULL;
1593 BOOL Success = FALSE;
1595 d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
1597 do {
1598 const struct ColorRegister *PalettePtr;
1599 UBYTE *PenListPtr;
1600 UBYTE *ImgPtr;
1601 UBYTE *ImgDestPtr;
1602 ULONG Remainder;
1603 ULONG n;
1604 ULONG y;
1606 PenList->nip_PenArray = MyAllocVecPooled(PaletteSize);
1607 if (NULL == PenList->nip_PenArray)
1608 break;
1610 PalettePtr = Palette;
1611 PenListPtr = PenList->nip_PenArray;
1612 for (n = 0; n < PaletteSize; n++)
1614 if (DimmedImage)
1616 *PenListPtr++ = ObtainBestPenA(inst->aio_Screen->ViewPort.ColorMap,
1617 PalettePtr->red << 23,
1618 PalettePtr->green << 23,
1619 PalettePtr->blue << 23,
1620 NULL);
1622 else
1624 *PenListPtr++ = ObtainBestPenA(inst->aio_Screen->ViewPort.ColorMap,
1625 PalettePtr->red << 24,
1626 PalettePtr->green << 24,
1627 PalettePtr->blue << 24,
1628 NULL);
1630 PalettePtr++;
1633 MappedImage = MyAllocVecPooled(img->nim_Height * ((img->nim_Width + 15) & 0xfff0));
1634 if (NULL == MappedImage)
1635 break;
1637 Remainder = ((img->nim_Width + 15) & 0xfff0) - img->nim_Width;
1638 ImgPtr = img->nim_ImageData;
1639 ImgDestPtr = MappedImage;
1640 for (y = 0; y < img->nim_Height; y++)
1642 ULONG x;
1644 for (x = 0; x < img->nim_Width; x++)
1646 *ImgDestPtr++ = PenList->nip_PenArray[*ImgPtr++];
1648 ImgDestPtr += Remainder;
1651 if (CyberGfxBase && GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX))
1653 WritePixelArray(MappedImage, 0, 0,
1654 (img->nim_Width + 15) & 0xfff0,
1655 rp, Left, Top,
1656 img->nim_Width, img->nim_Height,
1657 RECTFMT_LUT8);
1659 else
1661 struct RastPort rpTemp;
1663 InitRastPort(&rpTemp);
1664 rpTemp.BitMap = AllocBitMap((img->nim_Width + 15) & 0xfff0,
1665 img->nim_Height, 8, 0, rp->BitMap);
1666 if (NULL == rpTemp.BitMap)
1667 break;
1669 WritePixelArray8(rp, Left, Top,
1670 Left + img->nim_Width - 1,
1671 Top + img->nim_Height - 1,
1672 MappedImage, &rpTemp);
1674 FreeBitMap(rpTemp.BitMap);
1677 Success = TRUE;
1678 } while (0);
1680 if (MappedImage)
1681 MyFreeVecPooled(MappedImage);
1683 return Success;
1686 //-----------------------------------------------------------------------------
1688 static void DrawColorImage(struct InstanceData *inst, struct RastPort *rp,
1689 struct NewImagePenList *PenList, struct NewImage *img,
1690 UWORD Left, UWORD Top, const struct ColorRegister *Palette, ULONG PaletteSize,
1691 BOOL DimmedImage)
1693 BOOL Success;
1695 d1(kprintf("%s/%s/%ld: PaletteSize=%lu Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, img->nim_PaletteSize, Palette));
1697 if (PenList->nip_PenArray)
1699 MyFreeVecPooled(PenList->nip_PenArray);
1700 PenList->nip_PenArray = NULL;
1703 PenList->nip_PaletteSize = PaletteSize;
1705 if (CyberGfxBase && (GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8))
1707 Success = DrawTrueColorImage(rp, img, Left, Top, Palette, DimmedImage);
1709 else
1711 d1(KPrintF("%s/%s/%ld: CyberGfxBase=%08lx BMA_DEPTH=%ld\n", __FILE__, __FUNC__, __LINE__, CyberGfxBase, GetBitMapAttr(rp->BitMap, BMA_DEPTH)));
1712 Success = DrawRemappedImage(inst, rp, PenList, img,
1713 Left, Top, Palette, PaletteSize, DimmedImage);
1716 if (!Success && PenList->nip_PenArray)
1718 MyFreeVecPooled(PenList->nip_PenArray);
1719 PenList->nip_PenArray = NULL;
1723 //----------------------------------------------------------------------------------------
1725 static void ReadIcon(struct InstanceData *inst, CONST_STRPTR Filename, BPTR IconFh)
1727 static const LONG StopChunkList[] =
1729 ID_ICON, ID_FACE,
1730 ID_ICON, ID_IMAG,
1731 ID_ICON, ID_ARGB,
1733 STRPTR IconInfoName; // full filename of icon (including ".info")
1734 BPTR fd = BNULL;
1735 struct IFFHandle *iff = NULL;
1736 BOOL iffOpened = FALSE;
1738 do {
1739 BOOL FaceChunkOk = FALSE;
1740 BOOL Image1Ok = FALSE;
1741 LONG Result;
1743 IconInfoName = MyAllocVecPooled(1 + strlen(Filename) + strlen(".info"));
1744 if (NULL == IconInfoName)
1745 break;
1747 strcpy(IconInfoName, Filename);
1748 strcat(IconInfoName, ".info");
1750 if (IconFh)
1751 fd = IconFh;
1752 else
1753 fd = Open(IconInfoName, MODE_OLDFILE);
1754 d1(kprintf("%s/%s/%ld: fd=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, fd, IconInfoName));
1755 if (BNULL == fd)
1756 break;
1758 if (!ReadStandardIcon(inst, fd))
1759 break;
1761 // ---- End of standard icon data ------------------
1763 iff = AllocIFF();
1764 d1(kprintf(__FILE__ "/" "%s/%s/%ld: AlloCIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, IoErr()));
1765 if (NULL == iff)
1766 break;
1768 InitIFF(iff, IFFF_RSEEK | IFFF_READ, &StreamHook);
1769 iff->iff_Stream = (IPTR)fd;
1771 Result = OpenIFF(iff, IFFF_READ);
1772 d1(kprintf(__FILE__ "/" "%s/%s/%ld: OpenIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1773 if (RETURN_OK != Result)
1774 break;
1776 iffOpened = TRUE;
1778 Result = StopChunks(iff, StopChunkList, Sizeof(StopChunkList) / 2);
1779 d1(kprintf(__FILE__ "/" "%s/%s/%ld: StopChunks Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1780 if (RETURN_OK != Result)
1781 break;
1783 while (1)
1785 struct ContextNode *cn;
1787 Result = ParseIFF(iff, IFFPARSE_SCAN);
1788 if (RETURN_OK != Result)
1790 d1(kprintf(__FILE__ "/" "%s/%s/%ld: ParseIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1791 break;
1794 cn = CurrentChunk(iff);
1796 if (ID_FACE == cn->cn_ID)
1798 LONG Actual;
1800 d1(kprintf("%s/%s/%ld: FACE Chunk len=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size));
1801 if (cn->cn_Size != sizeof(struct FaceChunk))
1802 break;
1804 Actual = ReadChunkBytes(iff, &inst->aio_FaceChunk, sizeof(inst->aio_FaceChunk));
1805 if (Actual != sizeof(inst->aio_FaceChunk))
1806 break;
1808 inst->aio_FaceChunk.fc_MaxPaletteBytes = SCA_BE2WORD(inst->aio_FaceChunk.fc_MaxPaletteBytes);
1810 d1(kprintf("%s/%s/%ld: FACE id read OK.\n", __FILE__, __FUNC__, __LINE__));
1812 d1(kprintf("%s/%s/%ld: FACE Width=%ld Height=%ld Aspect=%02lx Flags=%02lx MaxPaletteBytes=%lu\n", \
1813 __FILE__, __FUNC__, __LINE__, \
1814 inst->aio_FaceChunk.fc_Width+1, inst->aio_FaceChunk.fc_Height+1,\
1815 inst->aio_FaceChunk.fc_AspectRatio,\
1816 inst->aio_FaceChunk.fc_Flags,\
1817 inst->aio_FaceChunk.fc_MaxPaletteBytes));
1819 inst->aio_Borderless = inst->aio_FaceChunk.fc_Flags & FCF_Borderless;
1821 FaceChunkOk = TRUE;
1823 else if (ID_IMAG == cn->cn_ID && cn->cn_Size >= sizeof(struct ImageChunk) && FaceChunkOk)
1825 d1(KPrintF("%s/%s/%ld: IMAG Chunk len=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size));
1827 if (Image1Ok)
1829 inst->aio_Image2 = ReadNewImage(iff, &inst->aio_FaceChunk);
1830 if (NULL == inst->aio_Image2)
1831 break;
1833 d1(kprintf("%s/%s/%ld: Image 2 read Ok.\n", __FILE__, __FUNC__, __LINE__));
1835 else
1837 inst->aio_Image1 = ReadNewImage(iff, &inst->aio_FaceChunk);
1838 if (NULL == inst->aio_Image1)
1839 break;
1841 d1(kprintf("%s/%s/%ld: Image 1 read Ok.\n", __FILE__, __FUNC__, __LINE__));
1842 Image1Ok = TRUE;
1845 else if (ID_ARGB == cn->cn_ID && cn->cn_Size >= sizeof(struct ImageChunk) && FaceChunkOk)
1847 d1(KPrintF("%s/%s/%ld: ARGB Chunk len=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size));
1849 if (Image1Ok)
1851 inst->aio_Image2 = ReadARGBImage(iff, &inst->aio_FaceChunk);
1852 if (NULL == inst->aio_Image2)
1853 break;
1855 d1(KPrintF("%s/%s/%ld: Image 2 read Ok.\n", __FILE__, __FUNC__, __LINE__));
1857 else
1859 inst->aio_Image1 = ReadARGBImage(iff, &inst->aio_FaceChunk);
1860 if (NULL == inst->aio_Image1)
1861 break;
1863 d1(KPrintF("%s/%s/%ld: Image 1 read Ok.\n", __FILE__, __FUNC__, __LINE__));
1864 Image1Ok = TRUE;
1868 } while (0);
1870 if (iff)
1872 if (iffOpened)
1873 CloseIFF(iff);
1875 FreeIFF(iff);
1877 if (fd && (BNULL == IconFh))
1878 Close(fd);
1880 if (IconInfoName)
1881 MyFreeVecPooled(IconInfoName);
1884 //----------------------------------------------------------------------------------------
1886 static BOOL WriteIcon(Class *cl, Object *o,
1887 const struct DiskObject *WriteDiskObject, CONST_STRPTR Filename)
1889 struct InstanceData *inst = INST_DATA(cl, o);
1890 STRPTR IconInfoName; // full filename of icon (including ".info")
1891 BPTR fd = (BPTR)NULL;
1892 struct IFFHandle *iff = NULL;
1893 BOOL iffOpened = FALSE;
1894 BOOL Success = FALSE;
1896 d1(KPrintF("%s/%s/%ld: START <%s>\n", __FILE__, __FUNC__, __LINE__, Filename));
1898 do {
1899 UWORD PaletteSize;
1900 struct FaceChunk fc;
1901 LONG Result;
1903 IconInfoName = MyAllocVecPooled(1 + strlen(Filename) + strlen(".info"));
1904 if (NULL == IconInfoName)
1906 SetIoErr(ERROR_NO_FREE_STORE);
1907 break;
1910 strcpy(IconInfoName, Filename);
1911 strcat(IconInfoName, ".info");
1913 fd = Open(IconInfoName, MODE_NEWFILE);
1914 d1(kprintf("%s/%s/%ld: fd=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, fd, IconInfoName));
1915 if ((BPTR)NULL == fd)
1916 break;
1918 if (!WriteStandardIcon(inst, WriteDiskObject, fd))
1919 break;
1921 // ---- End of standard icon data ------------------
1923 iff = AllocIFF();
1924 d1(kprintf(__FILE__ "/" "%s/%s/%ld: AlloCIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, IoErr()));
1925 if (NULL == iff)
1926 break;
1928 InitIFF(iff, IFFF_RSEEK | IFFF_WRITE, &StreamHook);
1929 iff->iff_Stream = (IPTR)fd;
1931 Result = OpenIFF(iff, IFFF_WRITE);
1932 d1(kprintf(__FILE__ "/" "%s/%s/%ld: OpenIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1933 if (RETURN_OK != Result)
1934 break;
1936 iffOpened = TRUE;
1938 Result = PushChunk(iff, ID_ICON, ID_FORM, IFFSIZE_UNKNOWN);
1939 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: PushChunk(ID_FORM) Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1940 if (RETURN_OK != Result)
1941 break;
1943 Result = PushChunk(iff, ID_ICON, ID_FACE, sizeof(struct FaceChunk));
1944 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: PushChunk(ID_FACE) Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1945 if (RETURN_OK != Result)
1946 break;
1948 fc = inst->aio_FaceChunk;
1950 if (NULL == inst->aio_Image1->nim_Palette)
1952 // make sure FaceChunk has correct size for ARGB image
1953 struct ARGBHeader *argbh = NULL;
1955 GetAttr(IDTA_ARGBImageData, o, (APTR) &argbh);
1956 if (argbh && argbh->argb_ImageData)
1958 fc.fc_Width = argbh->argb_Width - 1;
1959 fc.fc_Height = argbh->argb_Height - 1;
1963 PaletteSize = inst->aio_Image1->nim_PaletteSize;
1965 if (inst->aio_Image2 && inst->aio_Image2->nim_PaletteSize)
1967 if (inst->aio_Image2->nim_PaletteSize > PaletteSize)
1969 PaletteSize = inst->aio_Image2->nim_PaletteSize;
1973 PaletteSize = PaletteSize * 3 - 1;
1974 fc.fc_MaxPaletteBytes = PaletteSize * sizeof(struct ColorRegister) - 1;
1976 fc.fc_MaxPaletteBytes = SCA_WORD2BE(fc.fc_MaxPaletteBytes);
1978 if (sizeof(struct FaceChunk) != WriteChunkBytes(iff,
1979 &fc, sizeof(struct FaceChunk)))
1980 break;
1982 Result = PopChunk(iff); // ID_FACE
1983 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: PopChunk Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1984 if (RETURN_OK != Result)
1985 break;
1987 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_Image1->nim_Palette));
1988 if (inst->aio_Image1->nim_Palette)
1989 Result = WriteNewImage(iff, inst->aio_Image1);
1990 else
1991 Result = WriteARGBImage(cl, o, iff, inst->aio_Image1, IDTA_ARGBImageData);
1992 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: WriteNewImage(1) Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1993 if (RETURN_OK != Result)
1994 break;
1996 if (inst->aio_Image2)
1998 if (inst->aio_Image1->nim_Palette)
1999 Result = WriteNewImage(iff, inst->aio_Image2);
2000 else
2001 Result = WriteARGBImage(cl, o, iff, inst->aio_Image2, IDTA_SelARGBImageData);
2002 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: WriteNewImage(2)Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
2003 if (RETURN_OK != Result)
2004 break;
2007 Result = PopChunk(iff); // ID_ICON
2008 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: PopChunk Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
2009 if (RETURN_OK != Result)
2010 break;
2012 Success = TRUE;
2013 } while (0);
2015 if (iff)
2017 if (iffOpened)
2018 CloseIFF(iff);
2020 FreeIFF(iff);
2022 if (fd)
2023 Close(fd);
2024 if (IconInfoName)
2025 MyFreeVecPooled(IconInfoName);
2027 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
2029 return Success;
2032 //----------------------------------------------------------------------------------------
2034 static BOOL ReadStandardIcon(struct InstanceData *inst, BPTR fd)
2036 BOOL Success = FALSE;
2038 do {
2039 UWORD FileFormatRevision;
2040 ULONG len;
2042 inst->aio_DiskObject = MyAllocVecPooled(sizeof(struct DiskObject));
2043 if (NULL == inst->aio_DiskObject)
2044 break;
2046 #if defined(__AROS__)
2047 if (!ReadConvertStandardIcon(fd, inst->aio_DiskObject))
2048 break;
2049 #else
2050 if (sizeof(struct DiskObject) != FRead(fd, inst->aio_DiskObject, 1, sizeof(struct DiskObject)))
2051 break;
2052 #endif
2054 d1(kprintf("%s/%s/%ld: DiskObject read Ok, size=%ld.\n", __FILE__, __FUNC__, __LINE__, sizeof(struct DiskObject)));
2056 FileFormatRevision = ((ULONG) inst->aio_DiskObject->do_Gadget.UserData) & WB_DISKREVISIONMASK;
2058 d1(kprintf("%s/%s/%ld: do_Magic=%04lx Version=%04lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_Magic, inst->aio_DiskObject->do_Version));
2060 if (inst->aio_DiskObject->do_Magic == WB_DISKMAGIC)
2062 d1(kprintf("%s/%s/%ld: do_Magic = %04lx Version=%ld Revision=%ld\n", __FILE__, __FUNC__, __LINE__,\
2063 inst->aio_DiskObject->do_Magic, inst->aio_DiskObject->do_Version, FileFormatRevision));
2065 else
2066 break;
2068 d1(kprintf("%s/%s/%ld: File Position = %ld\n", __FILE__, __FUNC__, __LINE__, Seek(fd, 0, OFFSET_CURRENT)));
2069 d1(kprintf("%s/%s/%ld: DrawerData = %08lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_DrawerData));
2071 if (inst->aio_DiskObject->do_DrawerData)
2073 inst->aio_DiskObject->do_DrawerData = NULL;
2075 d1(kprintf("%s/%s/%ld: old-drawerdata expected, size=%ld.\n", __FILE__, __FUNC__, __LINE__, OLDDRAWERDATAFILESIZE));
2077 inst->aio_DiskObject->do_DrawerData = inst->aio_myDrawerData = MyAllocVecPooled(sizeof(struct DrawerData));
2078 if (NULL == inst->aio_myDrawerData)
2079 break;
2081 #if defined(__AROS__)
2082 if (!ReadConvertDrawerData(fd, inst->aio_myDrawerData))
2083 break;
2084 #else
2085 if (OLDDRAWERDATAFILESIZE != FRead(fd, inst->aio_myDrawerData, 1, OLDDRAWERDATAFILESIZE))
2086 break;
2087 #endif
2089 d1(kprintf("%s/%s/%ld: OldDrawerData read Ok.\n", __FILE__, __FUNC__, __LINE__));
2092 d1(kprintf("%s/%s/%ld: Image 1 expected, size=%ld\n", __FILE__, __FUNC__, __LINE__, sizeof(inst->aio_DoImage1)));
2094 #if defined(__AROS__)
2095 if (!ReadConvertImage(fd, &inst->aio_DoImage1))
2096 break;
2097 #else
2098 if (sizeof(inst->aio_DoImage1) != FRead(fd, &inst->aio_DoImage1, 1, sizeof(inst->aio_DoImage1)))
2099 break;
2100 #endif
2102 d1(kprintf("%s/%s/%ld: Image 1 read Ok.\n", __FILE__, __FUNC__, __LINE__));
2104 d1(kprintf("%s/%s/%ld: Image 1: Left=%d Top=%d Width=%d Height=%d Depth=%d\n", \
2105 __FILE__, __FUNC__, __LINE__, \
2106 inst->aio_DoImage1.LeftEdge, inst->aio_DoImage1.TopEdge, \
2107 inst->aio_DoImage1.Width, inst->aio_DoImage1.Height, inst->aio_DoImage1.Depth));
2109 len = RASSIZE(inst->aio_DoImage1.Width, inst->aio_DoImage1.Height) * inst->aio_DoImage1.Depth;
2111 d1(kprintf("%s/%s/%ld: ImageData 1 expected, size=%ld\n", __FILE__, __FUNC__, __LINE__, len));
2113 inst->aio_DiskObject->do_Gadget.GadgetRender = &inst->aio_DoImage1;
2115 inst->aio_DoImage1.ImageData = MyAllocVecPooled(len);
2116 if (NULL == inst->aio_DoImage1.ImageData)
2117 break;
2119 if (len != FRead(fd, inst->aio_DoImage1.ImageData, 1, len))
2120 break;
2122 d1(kprintf("%s/%s/%ld: ImageData 1 skipped Ok.\n", __FILE__, __FUNC__, __LINE__));
2124 inst->aio_DiskObject->do_Gadget.GadgetRender = &inst->aio_DoImage1;
2126 d1(kprintf("%s/%s/%ld: Gadget Flags = %08lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_Gadget.Flags));
2128 if (GFLG_GADGHIMAGE & inst->aio_DiskObject->do_Gadget.Flags)
2130 d1(kprintf("%s/%s/%ld: Image 2 expected, size=%ld\n", __FILE__, __FUNC__, __LINE__, sizeof(inst->aio_DoImage2)));
2133 #if defined(__AROS__)
2134 if (!ReadConvertImage(fd, &inst->aio_DoImage2))
2135 break;
2136 #else
2137 if (sizeof(inst->aio_DoImage2) != FRead(fd, &inst->aio_DoImage2, 1, sizeof(inst->aio_DoImage2)))
2138 break;
2139 #endif
2141 d1(kprintf("%s/%s/%ld: Image 2 read Ok.\n", __FILE__, __FUNC__, __LINE__));
2143 inst->aio_DiskObject->do_Gadget.SelectRender = &inst->aio_DoImage2;
2145 d1(kprintf("%s/%s/%ld: Image 2: Left=%d Top=%d Width=%d Height=%d Depth=%d\n", \
2146 __FILE__, __FUNC__, __LINE__, \
2147 inst->aio_DoImage2.LeftEdge, inst->aio_DoImage2.TopEdge, \
2148 inst->aio_DoImage2.Width, inst->aio_DoImage2.Height, inst->aio_DoImage2.Depth));
2150 len = RASSIZE(inst->aio_DoImage2.Width, inst->aio_DoImage2.Height) * inst->aio_DoImage2.Depth;
2152 d1(kprintf("%s/%s/%ld: ImageData 2 expected, size=%ld\n", __FILE__, __FUNC__, __LINE__, len));
2154 inst->aio_DoImage2.ImageData = MyAllocVecPooled(len);
2155 if (NULL == inst->aio_DoImage2.ImageData)
2156 break;
2158 if (len != FRead(fd, inst->aio_DoImage2.ImageData, 1, len))
2159 break;
2161 d1(kprintf("%s/%s/%ld: ImageData 2 read Ok.\n", __FILE__, __FUNC__, __LINE__));
2163 else
2165 inst->aio_DiskObject->do_Gadget.SelectRender = NULL;
2166 d1(kprintf("%s/%s/%ld: No alternate image.\n", __FILE__, __FUNC__, __LINE__));
2169 if (inst->aio_DiskObject->do_DefaultTool)
2171 inst->aio_DiskObject->do_DefaultTool = NULL;
2173 d1(kprintf("%s/%s/%ld: DefaultTool Length expected.\n", __FILE__, __FUNC__, __LINE__));
2174 if (sizeof(len) != FRead(fd, &len, 1, sizeof(len)))
2175 break;
2177 len = SCA_BE2LONG(len);
2179 d1(kprintf("%s/%s/%ld: DefaultTool length read Ok, length=%lu.\n", __FILE__, __FUNC__, __LINE__, len));
2181 if (len)
2183 inst->aio_DefaultTool = inst->aio_DiskObject->do_DefaultTool = MyAllocVecPooled(len);
2184 if (NULL == inst->aio_DiskObject->do_DefaultTool)
2185 break;
2187 if (len != FRead(fd, inst->aio_DiskObject->do_DefaultTool, 1, len))
2188 break;
2190 d1(kprintf("%s/%s/%ld: DefaultTool read Ok, <%s>.\n", \
2191 __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_DefaultTool));
2194 else
2196 d1(kprintf("%s/%s/%ld: No Default Tool.\n", __FILE__, __FUNC__, __LINE__));
2199 if (inst->aio_DiskObject->do_ToolTypes)
2201 inst->aio_DiskObject->do_ToolTypes = NULL;
2203 d1(kprintf("%s/%s/%ld: Expecting size of ToolTypes Array.\n", __FILE__, __FUNC__, __LINE__));
2204 if (sizeof(len) != FRead(fd, &len, 1, sizeof(len)))
2205 break;
2207 len = SCA_BE2LONG(len);
2209 d1(KPrintF("%s/%s/%ld: Size of ToolTypes Array read Ok, %lu.\n", __FILE__, __FUNC__, __LINE__, len));
2210 inst->aio_ToolTypesLength = len;
2211 if (len)
2213 short n;
2215 inst->aio_ToolTypes = inst->aio_DiskObject->do_ToolTypes = (STRPTR *) MyAllocVecPooled(len);
2216 if (NULL == inst->aio_DiskObject->do_ToolTypes)
2217 break;
2219 memset(inst->aio_DiskObject->do_ToolTypes, 0, len);
2221 for (n=0; n<(len-1)/sizeof(STRPTR); n++)
2223 ULONG sLen;
2225 if (sizeof(sLen) != FRead(fd, &sLen, 1, sizeof(sLen)))
2226 break;
2228 sLen = SCA_BE2LONG(sLen);
2230 inst->aio_DiskObject->do_ToolTypes[n] = MyAllocVecPooled(sLen);
2231 if (inst->aio_DiskObject->do_ToolTypes[n])
2232 FRead(fd, inst->aio_DiskObject->do_ToolTypes[n], 1, sLen);
2233 else
2234 Seek(fd, sLen, OFFSET_CURRENT);
2236 d1(kprintf("%s/%s/%ld: Read ToolType #%ld, len=%ld val=<%s>\n", \
2237 __FILE__, __FUNC__, __LINE__, n, sLen, inst->aio_DiskObject->do_ToolTypes[n]));
2241 else
2242 d1(kprintf("%s/%s/%ld: No ToolTypes.\n", __FILE__, __FUNC__, __LINE__));
2244 if (inst->aio_DiskObject->do_ToolWindow)
2246 inst->aio_DiskObject->do_ToolWindow = NULL;
2248 d1(kprintf("%s/%s/%ld: ToolWindow expected.\n", __FILE__, __FUNC__, __LINE__));
2250 if (sizeof(len) != FRead(fd, &len, 1, sizeof(len)))
2251 break;
2253 len = SCA_BE2LONG(len);
2255 inst->aio_ToolWindow = inst->aio_DiskObject->do_ToolWindow = MyAllocVecPooled(len);
2256 if (NULL == inst->aio_DiskObject->do_ToolWindow)
2257 break;
2259 if (len != FRead(fd, inst->aio_DiskObject->do_ToolWindow, 1, len))
2260 break;
2262 d1(kprintf("%s/%s/%ld: ToolWindow read ok, len=%ld\n", __FILE__, __FUNC__, __LINE__, len));
2264 else
2265 d1(kprintf("%s/%s/%ld: No ToolWindow.\n", __FILE__, __FUNC__, __LINE__));
2267 if (inst->aio_DiskObject->do_DrawerData && FileFormatRevision > 0 && FileFormatRevision <= WB_DISKREVISION)
2269 UBYTE *RemainingDrawerData = ((UBYTE *) inst->aio_myDrawerData) + OLDDRAWERDATAFILESIZE;
2271 ULONG ddSize = 6; // size of structs can be different on AROS
2272 // sizeof(struct DrawerData) - OLDDRAWERDATAFILESIZE
2274 d1(kprintf("%s/%s/%ld: remaining-drawerdata expected, size=%ld.\n", \
2275 __FILE__, __FUNC__, __LINE__, 6 /* sizeof(struct DrawerData) - OLDDRAWERDATAFILESIZE */));
2277 if (ddSize != FRead(fd, RemainingDrawerData, 1, ddSize))
2278 break;
2280 d1(kprintf("%s/%s/%ld: remaining-DrawerData read Ok.\n", __FILE__, __FUNC__, __LINE__));
2283 Success = TRUE;
2284 } while (0);
2286 return Success;
2289 //----------------------------------------------------------------------------------------
2291 static BOOL WriteStandardIcon(struct InstanceData *inst,
2292 const struct DiskObject *WriteDiskObject, BPTR fd)
2294 BOOL Success = FALSE;
2296 do {
2297 struct DiskObject wdo;
2298 ULONG len;
2299 ULONG val_be; // for storing values in BE order
2301 wdo = *WriteDiskObject;
2303 wdo.do_Gadget.UserData = (APTR) WB_DISKREVISION;
2305 #if defined(__AROS__)
2306 if (!WriteConvertStandardIcon(fd, &wdo))
2307 break;
2308 #else
2309 if (sizeof(struct DiskObject) != FWrite(fd, &wdo, 1, sizeof(struct DiskObject)))
2310 break;
2311 #endif
2313 d1(KPrintF("%s/%s/%ld: DiskObject written Ok, size=%ld.\n", __FILE__, __FUNC__, __LINE__, sizeof(struct DiskObject)));
2315 if (wdo.do_DrawerData)
2317 d1(KPrintF("%s/%s/%ld: write old-drawerdata, size=%ld.\n", __FILE__, __FUNC__, __LINE__, OLDDRAWERDATAFILESIZE));
2319 #if defined(__AROS__)
2320 if (!WriteConvertDrawerData(fd, inst->aio_myDrawerData))
2321 break;
2322 #else
2323 if (OLDDRAWERDATAFILESIZE != FWrite(fd, inst->aio_myDrawerData, 1, OLDDRAWERDATAFILESIZE))
2324 break;
2325 #endif
2327 d1(KPrintF("%s/%s/%ld: OldDrawerData written Ok.\n", __FILE__, __FUNC__, __LINE__));
2330 d1(KPrintF("%s/%s/%ld: write Image 1, size=%ld\n", __FILE__, __FUNC__, __LINE__, sizeof(inst->aio_DoImage1)));
2332 #if defined(__AROS__)
2333 if (!WriteConvertImage(fd, &inst->aio_DoImage1))
2334 break;
2335 #else
2336 if (sizeof(inst->aio_DoImage1) != FWrite(fd, &inst->aio_DoImage1, 1, sizeof(inst->aio_DoImage1)))
2337 break;
2338 #endif
2340 d1(KPrintF("%s/%s/%ld: Image 1 written Ok.\n", __FILE__, __FUNC__, __LINE__));
2342 len = RASSIZE(inst->aio_DoImage1.Width, inst->aio_DoImage1.Height) * inst->aio_DoImage1.Depth;
2344 d1(KPrintF("%s/%s/%ld: write ImageData 1, size=%ld\n", __FILE__, __FUNC__, __LINE__, len));
2346 if (len != FWrite(fd, inst->aio_DoImage1.ImageData, 1, len))
2347 break;
2349 d1(KPrintF("%s/%s/%ld: ImageData 1 written Ok.\n", __FILE__, __FUNC__, __LINE__));
2351 if (GFLG_GADGHIMAGE & wdo.do_Gadget.Flags)
2353 d1(KPrintF("%s/%s/%ld: write Image 2, size=%ld\n", __FILE__, __FUNC__, __LINE__, sizeof(inst->aio_DoImage2)));
2355 #if defined(__AROS__)
2356 if (!WriteConvertImage(fd, &inst->aio_DoImage2))
2357 break;
2358 #else
2359 if (sizeof(inst->aio_DoImage2) != FWrite(fd, &inst->aio_DoImage2, 1, sizeof(inst->aio_DoImage2)))
2360 break;
2361 #endif
2363 d1(KPrintF("%s/%s/%ld: Image 2 written Ok.\n", __FILE__, __FUNC__, __LINE__));
2365 len = RASSIZE(inst->aio_DoImage2.Width, inst->aio_DoImage2.Height) * inst->aio_DoImage2.Depth;
2367 d1(KPrintF("%s/%s/%ld: write ImageData 2, size=%ld\n", __FILE__, __FUNC__, __LINE__, len));
2369 if (len != FWrite(fd, inst->aio_DoImage2.ImageData, 1, len))
2370 break;
2372 d1(KPrintF("%s/%s/%ld: ImageData 2 written Ok.\n", __FILE__, __FUNC__, __LINE__));
2375 if (wdo.do_DefaultTool)
2377 len = 1 + strlen(wdo.do_DefaultTool);
2379 d1(KPrintF("%s/%s/%ld: write DefaultTool Length.\n", __FILE__, __FUNC__, __LINE__));
2380 val_be = SCA_LONG2BE(len);
2381 if (sizeof(val_be) != FWrite(fd, &val_be, 1, sizeof(val_be)))
2382 break;
2384 d1(KPrintF("%s/%s/%ld: DefaultTool length written Ok, length=%lu.\n", __FILE__, __FUNC__, __LINE__, val_be));
2386 if (len)
2388 if (len != FWrite(fd, wdo.do_DefaultTool, 1, len))
2389 break;
2391 d1(KPrintF("%s/%s/%ld: DefaultTool written Ok, <%s>.\n", \
2392 __FILE__, __FUNC__, __LINE__, wdo.do_DefaultTool));
2396 if (wdo.do_ToolTypes)
2398 short n;
2400 for (n = 0; wdo.do_ToolTypes[n]; n++)
2403 len = (1 + n) * sizeof(STRPTR);
2405 d1(KPrintF("%s/%s/%ld: write size of ToolTypes Array = %ld.\n", __FILE__, __FUNC__, __LINE__, len));
2406 val_be = SCA_LONG2BE(len);
2407 if (sizeof(val_be) != FWrite(fd, &val_be, 1, sizeof(val_be)))
2408 break;
2410 d1(KPrintF("%s/%s/%ld: Size of ToolTypes Array written Ok, %lu.\n", __FILE__, __FUNC__, __LINE__, len));
2413 for (n=0; n<(len-1) / sizeof(STRPTR); n++)
2415 ULONG sLen;
2417 sLen = 1 + strlen(wdo.do_ToolTypes[n]);
2419 val_be = SCA_LONG2BE(sLen);
2420 if (sizeof(val_be) != FWrite(fd, &val_be, 1, sizeof(val_be)))
2421 break;
2423 if (sLen != FWrite(fd, wdo.do_ToolTypes[n], 1, sLen))
2424 break;
2426 d1(KPrintF("%s/%s/%ld: ToolType #%ld written, len=%ld val=<%s>\n", \
2427 __FILE__, __FUNC__, __LINE__, n, sLen, wdo.do_ToolTypes[n]));
2431 if (wdo.do_ToolWindow)
2433 len = 1 + strlen(wdo.do_ToolWindow);
2435 d1(KPrintF("%s/%s/%ld: write ToolWindow.\n", __FILE__, __FUNC__, __LINE__));
2437 val_be = SCA_LONG2BE(len);
2438 if (sizeof(val_be) != FWrite(fd, &val_be, 1, sizeof(val_be)))
2439 break;
2441 if (len != FWrite(fd, wdo.do_ToolWindow, 1, len))
2442 break;
2444 d1(KPrintF("%s/%s/%ld: ToolWindow written ok, len=%ld\n", __FILE__, __FUNC__, __LINE__, len));
2447 if (wdo.do_DrawerData)
2449 UBYTE *RemainingDrawerData = ((UBYTE *) wdo.do_DrawerData) + OLDDRAWERDATAFILESIZE;
2450 ULONG ddSize = 6; // size of structs can be different on AROS
2451 // sizeof(struct DrawerData) - OLDDRAWERDATAFILESIZE;
2453 d1(KPrintF("%s/%s/%ld: write remaining-drawerdata, size=%ld.\n", \
2454 __FILE__, __FUNC__, __LINE__, 6 /* sizeof(struct DrawerData) - OLDDRAWERDATAFILESIZE */));
2456 if (ddSize != FWrite(fd, RemainingDrawerData, 1, ddSize))
2457 break;
2459 d1(KPrintF("%s/%s/%ld: remaining-DrawerData written Ok.\n", __FILE__, __FUNC__, __LINE__));
2462 Success = TRUE;
2463 } while (0);
2465 return Success;
2468 //----------------------------------------------------------------------------------------
2470 static struct NewImage *ReadNewImage(struct IFFHandle *iff, const struct FaceChunk *fc)
2472 struct NewImage *ni = NULL;
2473 BOOL Success = FALSE;
2474 UBYTE *UnCompressBuffer = NULL;
2476 do {
2477 ULONG PaletteSize;
2479 ni = MyAllocVecPooled(sizeof(struct NewImage));
2480 if (NULL == ni)
2481 break;
2483 memset(ni, 0, sizeof(struct NewImage));
2485 if (sizeof(ni->nim_ImageChunk) != ReadChunkBytes(iff, &ni->nim_ImageChunk, sizeof(ni->nim_ImageChunk)))
2486 break;
2488 ni->nim_ImageChunk.ic_NumImageBytes = SCA_BE2WORD(ni->nim_ImageChunk.ic_NumImageBytes);
2489 ni->nim_ImageChunk.ic_NumPaletteBytes = SCA_BE2WORD(ni->nim_ImageChunk.ic_NumPaletteBytes);
2491 d1(kprintf("%s/%s/%ld: IMAG Chunk Read Ok.\n", __FILE__, __FUNC__, __LINE__));
2493 d1(kprintf("%s/%s/%ld: Transparent=%ld ic_PaletteSize=%ld Flags=%02lx ImgComp=%02lx PalComp=%02lx BitsPerPixel=%ld NumImageBytes=%ld NumPaletteBytes=%ld\n",\
2494 __FILE__, __FUNC__, __LINE__, \
2495 (ULONG) ni->nim_ImageChunk.ic_TransparentColor,\
2496 (ULONG) ni->nim_ImageChunk.ic_PaletteSize, \
2497 (ULONG) ni->nim_ImageChunk.ic_Flags, \
2498 (ULONG) ni->nim_ImageChunk.ic_ImageCompressionType,\
2499 (ULONG) ni->nim_ImageChunk.ic_PaletteCompressionType, \
2500 (ULONG) ni->nim_ImageChunk.ic_BitsPerPixel,\
2501 (ULONG) ni->nim_ImageChunk.ic_NumImageBytes,
2502 (ULONG) ni->nim_ImageChunk.ic_NumPaletteBytes));
2504 ni->nim_Width = 1 + fc->fc_Width;
2505 ni->nim_Height = 1 + fc->fc_Height;
2506 ni->nim_PaletteSize = ni->nim_ImageChunk.ic_PaletteSize ? (1 + ni->nim_ImageChunk.ic_PaletteSize) : 0;
2508 PaletteSize = ni->nim_PaletteSize * sizeof(struct ColorRegister);
2510 ni->nim_Palette = MyAllocVecPooled(PaletteSize);
2511 d1(kprintf("%s/%s/%ld: nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, ni->nim_Palette));
2512 if (NULL == ni->nim_Palette)
2513 break;
2515 UnCompressBuffer = MyAllocVecPooled(1 + max(ni->nim_ImageChunk.ic_NumImageBytes, ni->nim_ImageChunk.ic_NumPaletteBytes));
2516 d1(kprintf("%s/%s/%ld: UnCompressBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, UnCompressBuffer));
2517 if (NULL == UnCompressBuffer)
2518 break;
2520 ni->nim_ImageData = MyAllocVecPooled(ni->nim_Width * ni->nim_Height);
2521 d1(kprintf("%s/%s/%ld: nim_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, ni->nim_ImageData));
2522 if (NULL == ni->nim_ImageData)
2523 break;
2525 if (1 + ni->nim_ImageChunk.ic_NumImageBytes != ReadChunkBytes(iff, UnCompressBuffer, 1 + ni->nim_ImageChunk.ic_NumImageBytes))
2526 break;
2528 d1(kprintf("%s/%s/%ld: Image Data Read Ok.\n", __FILE__, __FUNC__, __LINE__));
2530 d1(kprintf("%s/%s/%ld: BufferData = %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n",\
2531 __FILE__, __FUNC__, __LINE__, \
2532 UnCompressBuffer[0], UnCompressBuffer[1], UnCompressBuffer[2], UnCompressBuffer[3], \
2533 UnCompressBuffer[4], UnCompressBuffer[5], UnCompressBuffer[6], UnCompressBuffer[7]));
2535 if (cmpNone == ni->nim_ImageChunk.ic_ImageCompressionType)
2537 d1(KPrintF("%s/%s/%ld: ic_NumImageBytes=%lu w*x=%lu\n", \
2538 __FILE__, __FUNC__, __LINE__, ni->nim_ImageChunk.ic_NumImageBytes, ni->nim_Width * ni->nim_Height));
2540 CopyMem(UnCompressBuffer, ni->nim_ImageData,
2541 min(ni->nim_ImageChunk.ic_NumImageBytes, ni->nim_Width * ni->nim_Height));
2543 else if (cmpByteRun1 == ni->nim_ImageChunk.ic_ImageCompressionType)
2545 d1(KPrintF("%s/%s/%ld: decompressing Image Data.\n", __FILE__, __FUNC__, __LINE__));
2547 if (!DecodeData(UnCompressBuffer, ni->nim_ImageData,
2548 ni->nim_ImageChunk.ic_NumImageBytes, ni->nim_Width * ni->nim_Height,
2549 ni->nim_ImageChunk.ic_BitsPerPixel))
2551 d1(KPrintF("%s/%s/%ld: Image Data decompression failed.\n", __FILE__, __FUNC__, __LINE__));
2552 break;
2555 else
2557 // unknown image compression type
2558 d1(KPrintF("%s/%s/%ld: unknown Image Data decompression type.\n", __FILE__, __FUNC__, __LINE__));
2559 break;
2562 d1(KPrintF("%s/%s/%ld: Image Data Decoded Ok.\n", __FILE__, __FUNC__, __LINE__));
2564 #if 0
2565 // Dump ImageData
2566 if (ni->nim_ImageData)
2568 short n;
2570 kprintf("-------ImageData1----------\n"));
2571 for (n=0; n<ni->nim_Width * ni->nim_Height; n++)
2573 if (0 == n % 16)
2574 kprintf("\n%04lx: ", n);
2575 printf("%02lx ", ni->nim_ImageData[n]);
2577 kprintf("\n");
2579 #endif
2581 if (ni->nim_ImageChunk.ic_Flags & ICF_HasPalette)
2583 if (1 + ni->nim_ImageChunk.ic_NumPaletteBytes != ReadChunkBytes(iff, UnCompressBuffer, 1 + ni->nim_ImageChunk.ic_NumPaletteBytes))
2584 break;
2585 d1(kprintf("%s/%s/%ld: Palette Data Read Ok.\n", __FILE__, __FUNC__, __LINE__));
2587 if (cmpNone == ni->nim_ImageChunk.ic_PaletteCompressionType)
2589 if (1 + ni->nim_ImageChunk.ic_NumPaletteBytes != PaletteSize)
2590 break;
2592 CopyMem(UnCompressBuffer, ni->nim_Palette, PaletteSize);
2594 else if (cmpByteRun1 == ni->nim_ImageChunk.ic_PaletteCompressionType)
2596 d1(KPrintF("%s/%s/%ld: decompressing Palette Data.\n", __FILE__, __FUNC__, __LINE__));
2598 if (!DecodeData(UnCompressBuffer, (UBYTE *) ni->nim_Palette,
2599 1 + ni->nim_ImageChunk.ic_NumPaletteBytes, PaletteSize,
2602 d1(KPrintF("%s/%s/%ld: Palette Data decompression failed.\n", __FILE__, __FUNC__, __LINE__));
2603 break;
2606 else
2608 // unknown palette compression type
2609 d1(KPrintF("%s/%s/%ld: unknown Palette Data decompression type.\n", __FILE__, __FUNC__, __LINE__));
2610 break;
2613 d1(kprintf("%s/%s/%ld: Palette Data Decoded Ok.\n", __FILE__, __FUNC__, __LINE__));
2614 #if 0
2615 kprintf("-------Palette----------\n");
2616 for (n=0; n<ni->nim_PaletteSize; n++)
2618 kprintf("Palette : r=%02lx g=%02lx b=%02lx\n",
2619 ni->nim_Palette[n].red, ni->nim_Palette[n].green, ni->nim_Palette[n].blue);
2621 #endif
2624 Success = TRUE;
2625 } while (0);
2627 d1(kprintf("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
2629 if (UnCompressBuffer)
2630 MyFreeVecPooled(UnCompressBuffer);
2632 if (!Success)
2633 FreeNewImage(&ni);
2635 return ni;
2638 //----------------------------------------------------------------------------------------
2640 static struct NewImage *ReadARGBImage(struct IFFHandle *iff, const struct FaceChunk *fc)
2642 struct NewImage *ni = NULL;
2643 BOOL Success = FALSE;
2644 UBYTE *UnCompressBuffer = NULL;
2646 do {
2647 ULONG ImageSize;
2648 ULONG ReadLength;
2649 ULONG BytesRead;
2650 z_stream stream;
2651 int zError;
2653 ni = MyAllocVecPooled(sizeof(struct NewImage));
2654 if (NULL == ni)
2655 break;
2657 memset(ni, 0, sizeof(struct NewImage));
2659 if (sizeof(ni->nim_ImageChunk) != ReadChunkBytes(iff, &ni->nim_ImageChunk, sizeof(ni->nim_ImageChunk)))
2660 break;
2662 ni->nim_ImageChunk.ic_NumImageBytes = SCA_BE2WORD(ni->nim_ImageChunk.ic_NumImageBytes);
2663 ni->nim_ImageChunk.ic_NumPaletteBytes = SCA_BE2WORD(ni->nim_ImageChunk.ic_NumPaletteBytes);
2665 d1(KPrintF("%s/%s/%ld: ARGB Chunk Read Ok.\n", __FILE__, __FUNC__, __LINE__));
2667 d1(KPrintF("%s/%s/%ld: Transparent=%ld ic_PaletteSize=%ld Flags=%02lx ImgComp=%02lx PalComp=%02lx BitsPerPixel=%ld NumImageBytes=%ld NumPaletteBytes=%ld\n",\
2668 __FILE__, __FUNC__, __LINE__, \
2669 (ULONG) ni->nim_ImageChunk.ic_TransparentColor,\
2670 (ULONG) ni->nim_ImageChunk.ic_PaletteSize, \
2671 (ULONG) ni->nim_ImageChunk.ic_Flags, \
2672 (ULONG) ni->nim_ImageChunk.ic_ImageCompressionType,\
2673 (ULONG) ni->nim_ImageChunk.ic_PaletteCompressionType, \
2674 (ULONG) ni->nim_ImageChunk.ic_BitsPerPixel,\
2675 (ULONG) ni->nim_ImageChunk.ic_NumImageBytes,
2676 (ULONG) ni->nim_ImageChunk.ic_NumPaletteBytes));
2678 ni->nim_ARGBheader.argb_Width = ni->nim_Width = 1 + fc->fc_Width;
2679 ni->nim_ARGBheader.argb_Height = ni->nim_Height = 1 + fc->fc_Height;
2680 ni->nim_PaletteSize = 1 + ni->nim_ImageChunk.ic_PaletteSize;
2682 ImageSize = ni->nim_ImageChunk.ic_NumImageBytes + 1;
2683 ReadLength = ((ImageSize + 1) >> 1) << 1; // round to next even number
2685 UnCompressBuffer = MyAllocVecPooled(ReadLength);
2686 d1(KPrintF("%s/%s/%ld: UnCompressBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, UnCompressBuffer));
2687 if (NULL == UnCompressBuffer)
2688 break;
2690 BytesRead = ReadChunkBytes(iff, UnCompressBuffer, ImageSize);
2691 d1(KPrintF("%s/%s/%ld: ReadLength=%lu BytesRead=%lu\n", __FILE__, __FUNC__, __LINE__, ImageSize, BytesRead));
2692 if (BytesRead != ImageSize)
2693 break;
2695 stream.avail_out = ni->nim_Width * ni->nim_Height * sizeof(struct ARGB);
2697 ni->nim_ImageData = MyAllocVecPooled(stream.avail_out);
2698 d1(KPrintF("%s/%s/%ld: nim_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, ni->nim_ImageData));
2699 if (NULL == ni->nim_ImageData)
2700 break;
2702 ni->nim_ARGBheader.argb_ImageData = (struct ARGB *) ni->nim_ImageData;
2704 stream.next_in = UnCompressBuffer;
2705 stream.avail_in = ImageSize;
2706 stream.next_out = ni->nim_ImageData;
2707 stream.zalloc = (alloc_func) ZLibAlloc;
2708 stream.zfree = (free_func) ZLibFree;
2710 d1(KPrintF("%s/%s/%ld: avail_out=%ld\n", __FILE__, __FUNC__, __LINE__, stream.avail_out));
2712 zError = inflateInit(&stream);
2713 d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError));
2714 if (Z_OK != zError)
2715 break;
2717 zError = inflate(&stream, Z_FINISH);
2718 d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError));
2719 if (Z_STREAM_END != zError)
2721 inflateEnd(&stream);
2722 break;
2725 zError = inflateEnd(&stream);
2726 d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError));
2727 if (Z_OK != zError)
2728 break;
2730 Success = TRUE;
2731 } while (0);
2733 d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
2735 if (UnCompressBuffer)
2736 MyFreeVecPooled(UnCompressBuffer);
2738 if (!Success)
2739 FreeNewImage(&ni);
2741 return ni;
2744 //----------------------------------------------------------------------------------------
2746 static LONG WriteNewImage(struct IFFHandle *iff, const struct NewImage *ni)
2748 UBYTE *PaletteCompressed = NULL;
2749 UBYTE *ImageDataCompressed = NULL;
2750 LONG ErrorCode;
2752 d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
2754 do {
2755 struct ImageChunk SaveImageChunk;
2756 ULONG Size;
2757 UWORD NumImageBytesOld;
2758 UWORD NumPaletteBytesOld;
2760 SaveImageChunk = ni->nim_ImageChunk;
2762 if (ni->nim_PaletteSize && ni->nim_Palette
2763 && (ni->nim_ImageChunk.ic_Flags & ICF_HasPalette))
2765 SaveImageChunk.ic_Flags |= ICF_HasPalette;
2767 Size = ni->nim_PaletteSize * sizeof(struct ColorRegister);
2768 PaletteCompressed = EncodeData(8,
2769 &SaveImageChunk.ic_NumPaletteBytes,
2770 Size,
2771 (UBYTE *) ni->nim_Palette);
2772 d1(KPrintF("%s/%s/%ld: PaletteCompressed=%08lx\n", __FILE__, __FUNC__, __LINE__, PaletteCompressed));
2773 if (NULL == PaletteCompressed)
2775 SetIoErr(ErrorCode = ERROR_NO_FREE_STORE);
2776 break;
2779 d1(KPrintF("%s/%s/%ld: Size=%lu ic_NumPaletteBytes=%lu\n", __FILE__, __FUNC__, __LINE__, Size, SaveImageChunk.ic_NumPaletteBytes));
2781 if (Size == SaveImageChunk.ic_NumPaletteBytes)
2782 SaveImageChunk.ic_PaletteCompressionType = cmpNone;
2783 else
2784 SaveImageChunk.ic_PaletteCompressionType = cmpByteRun1;
2786 else
2788 SaveImageChunk.ic_Flags &= ~ICF_HasPalette;
2789 SaveImageChunk.ic_NumPaletteBytes = 0;
2792 Size = ni->nim_Width * ni->nim_Height;
2793 ImageDataCompressed = EncodeData(SaveImageChunk.ic_BitsPerPixel,
2794 &SaveImageChunk.ic_NumImageBytes,
2795 Size,
2796 ni->nim_ImageData);
2797 d1(KPrintF("%s/%s/%ld: ImageDataCompressed=%08lx\n", __FILE__, __FUNC__, __LINE__, ImageDataCompressed));
2798 if (NULL == ImageDataCompressed)
2800 SetIoErr(ErrorCode = ERROR_NO_FREE_STORE);
2801 break;
2804 d1(KPrintF("%s/%s/%ld: Depth=%ld Size=%lu ic_NumImageBytes=%lu\n", __FILE__, __FUNC__, __LINE__, SaveImageChunk.ic_BitsPerPixel, Size, SaveImageChunk.ic_NumImageBytes));
2806 d1(KPrintF("%s/%s/%ld: ImageData = %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n",\
2807 __FILE__, __FUNC__, __LINE__, \
2808 ni->nim_ImageData[0], ni->nim_ImageData[1], ni->nim_ImageData[2], ni->nim_ImageData[3], \
2809 ni->nim_ImageData[4], ni->nim_ImageData[5], ni->nim_ImageData[6], ni->nim_ImageData[7]));
2810 d1(KPrintF("%s/%s/%ld: ImageDataCompressed = %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n",\
2811 __FILE__, __FUNC__, __LINE__, \
2812 ImageDataCompressed[0], ImageDataCompressed[1], ImageDataCompressed[2], ImageDataCompressed[3], \
2813 ImageDataCompressed[4], ImageDataCompressed[5], ImageDataCompressed[6], ImageDataCompressed[7]));
2815 if (Size == SaveImageChunk.ic_NumImageBytes)
2816 SaveImageChunk.ic_ImageCompressionType = cmpNone;
2817 else
2818 SaveImageChunk.ic_ImageCompressionType = cmpByteRun1;
2820 SaveImageChunk.ic_NumImageBytes--;
2821 if (SaveImageChunk.ic_NumPaletteBytes)
2822 SaveImageChunk.ic_NumPaletteBytes--;
2824 ErrorCode = PushChunk(iff, ID_ICON, ID_IMAG, IFFSIZE_UNKNOWN);
2825 d1(KPrintF("%s/%s/%ld: PushChunk(ID_IMAG) returned %ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode));
2826 if (RETURN_OK != ErrorCode)
2827 break;
2829 NumImageBytesOld = SaveImageChunk.ic_NumImageBytes;
2830 NumPaletteBytesOld = SaveImageChunk.ic_NumPaletteBytes;
2831 SaveImageChunk.ic_NumImageBytes = SCA_WORD2BE(SaveImageChunk.ic_NumImageBytes);
2832 SaveImageChunk.ic_NumPaletteBytes = SCA_WORD2BE(SaveImageChunk.ic_NumPaletteBytes);
2834 if (sizeof(SaveImageChunk) != WriteChunkBytes(iff,
2835 &SaveImageChunk, sizeof(SaveImageChunk)))
2837 d1(KPrintF("%s/%s/%ld: WriteChunk(imagehunk) failed\n", __FILE__, __FUNC__, __LINE__));
2838 ErrorCode = IoErr();
2839 break;
2842 SaveImageChunk.ic_NumImageBytes = NumImageBytesOld;
2843 SaveImageChunk.ic_NumPaletteBytes = NumPaletteBytesOld;
2845 Size = SaveImageChunk.ic_NumImageBytes + 1;
2847 if (Size != WriteChunkBytes(iff, ImageDataCompressed, Size))
2849 d1(KPrintF("%s/%s/%ld: WriteChunk(image) failed\n", __FILE__, __FUNC__, __LINE__));
2850 ErrorCode = IoErr();
2851 break;
2854 if (SaveImageChunk.ic_NumPaletteBytes)
2856 Size = SaveImageChunk.ic_NumPaletteBytes + 1;
2858 if (Size != WriteChunkBytes(iff, PaletteCompressed, Size))
2860 d1(KPrintF("%s/%s/%ld: WriteChunk(palette) failed\n", __FILE__, __FUNC__, __LINE__));
2861 ErrorCode = IoErr();
2862 break;
2866 ErrorCode = PopChunk(iff);
2867 d1(KPrintF("%s/%s/%ld: PopChunk returned %ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode));
2868 if (RETURN_OK != ErrorCode)
2869 break;
2870 } while (0);
2872 if (ImageDataCompressed)
2873 MyFreeVecPooled(ImageDataCompressed);
2875 if (PaletteCompressed)
2876 MyFreeVecPooled(PaletteCompressed);
2878 d1(KPrintF("%s/%s/%ld: END ErrorCode=%ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode));
2880 return ErrorCode;
2883 //----------------------------------------------------------------------------------------
2885 static LONG WriteARGBImage(Class *cl, Object *o, struct IFFHandle *iff,
2886 const struct NewImage *ni, ULONG ARGBImageTag)
2888 UBYTE *ImageDataCompressed = NULL;
2889 LONG ErrorCode;
2890 z_stream stream;
2892 d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
2894 memset(&stream, 0, sizeof(stream));
2896 do {
2897 struct ImageChunk SaveImageChunk;
2898 struct ARGBHeader *argbh = NULL;
2899 ULONG Size;
2900 UWORD NumImageBytesOld; // remember size before endian conversion
2901 int zError;
2903 memset(&argbh, 0, sizeof(argbh));
2905 SaveImageChunk = ni->nim_ImageChunk;
2907 SaveImageChunk.ic_Flags &= ~ICF_HasPalette;
2908 SaveImageChunk.ic_NumPaletteBytes = 0;
2909 SaveImageChunk.ic_BitsPerPixel = 0; // MUST be 0 for OS4 to recognize icon!
2911 GetAttr(ARGBImageTag, o, (APTR) &argbh);
2912 d1(KPrintF("%s/%s/%ld: argbh=%08lx argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, argbh, argbh->argb_ImageData));
2913 if (NULL == argbh->argb_ImageData)
2915 SetIoErr(ErrorCode = ERROR_OBJECT_WRONG_TYPE);
2916 break;
2919 stream.avail_in = Size = argbh->argb_Width * argbh->argb_Height * sizeof(struct ARGB);
2920 stream.next_in = (Bytef *) argbh->argb_ImageData;
2922 stream.avail_out = Size;
2923 stream.next_out = ImageDataCompressed = MyAllocVecPooled(stream.avail_out);
2924 d1(KPrintF("%s/%s/%ld: ImageDataCompressed=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, ImageDataCompressed, Size));
2925 if (NULL == ImageDataCompressed)
2927 SetIoErr(ErrorCode = ERROR_NO_FREE_STORE);
2928 break;
2931 stream.zalloc = (alloc_func) ZLibAlloc;
2932 stream.zfree = (free_func) ZLibFree;
2933 stream.opaque = Z_NULL;
2935 zError = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
2936 d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError));
2937 if (Z_OK != zError)
2939 SetIoErr(ErrorCode = ERROR_NO_FREE_STORE);
2940 break;
2943 zError = deflate(&stream, Z_FINISH);
2944 d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError));
2945 if (Z_STREAM_END != zError)
2947 SetIoErr(ErrorCode = ERROR_NO_FREE_STORE);
2948 break;
2951 SaveImageChunk.ic_NumImageBytes = Size - stream.avail_out;
2953 d1(KPrintF("%s/%s/%ld: Depth=%ld Size=%lu ic_NumImageBytes=%lu\n", __FILE__, __FUNC__, __LINE__, SaveImageChunk.ic_BitsPerPixel, Size, SaveImageChunk.ic_NumImageBytes));
2955 if (Size == SaveImageChunk.ic_NumImageBytes)
2956 SaveImageChunk.ic_ImageCompressionType = cmpNone;
2957 else
2958 SaveImageChunk.ic_ImageCompressionType = cmpByteRun1;
2960 SaveImageChunk.ic_NumImageBytes--;
2962 ErrorCode = PushChunk(iff, ID_ICON, ID_ARGB, IFFSIZE_UNKNOWN);
2963 d1(KPrintF("%s/%s/%ld: PushChunk(ID_ARGB) returned %ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode));
2964 if (RETURN_OK != ErrorCode)
2965 break;
2967 NumImageBytesOld = SaveImageChunk.ic_NumImageBytes;
2968 SaveImageChunk.ic_NumImageBytes = SCA_WORD2BE(SaveImageChunk.ic_NumImageBytes);
2970 if (sizeof(SaveImageChunk) != WriteChunkBytes(iff,
2971 &SaveImageChunk, sizeof(SaveImageChunk)))
2973 d1(KPrintF("%s/%s/%ld: WriteChunk(imagehunk) failed\n", __FILE__, __FUNC__, __LINE__));
2974 ErrorCode = IoErr();
2975 break;
2978 SaveImageChunk.ic_NumImageBytes = NumImageBytesOld;
2979 Size = SaveImageChunk.ic_NumImageBytes + 1;
2981 if (Size != WriteChunkBytes(iff, ImageDataCompressed, Size))
2983 d1(KPrintF("%s/%s/%ld: WriteChunk(image) failed\n", __FILE__, __FUNC__, __LINE__));
2984 ErrorCode = IoErr();
2985 break;
2988 ErrorCode = PopChunk(iff);
2989 d1(KPrintF("%s/%s/%ld: PopChunk returned %ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode));
2990 if (RETURN_OK != ErrorCode)
2991 break;
2992 } while (0);
2994 if (ImageDataCompressed)
2995 MyFreeVecPooled(ImageDataCompressed);
2997 (void) deflateEnd(&stream);
2999 d1(KPrintF("%s/%s/%ld: END ErrorCode=%ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode));
3001 return ErrorCode;
3004 //----------------------------------------------------------------------------------------
3006 static void FreeNewImage(struct NewImage **ni)
3008 if (*ni)
3010 if ((*ni)->nim_ImageData)
3012 MyFreeVecPooled((*ni)->nim_ImageData);
3013 (*ni)->nim_ImageData = NULL;
3015 if ((*ni)->nim_Palette)
3017 MyFreeVecPooled((*ni)->nim_Palette);
3018 (*ni)->nim_Palette = NULL;
3020 MyFreeVecPooled(*ni);
3021 *ni = NULL;
3025 //----------------------------------------------------------------------------------------
3027 static BOOL CloneNewImage(struct NewImage **niClone, const struct NewImage *niSrc)
3029 BOOL Success = FALSE;
3031 do {
3032 if (niSrc)
3034 size_t len;
3036 *niClone = MyAllocVecPooled(sizeof(struct NewImage));
3037 if (NULL == *niClone)
3038 break;
3040 if (niSrc->nim_ImageData)
3042 // Clone nim_ImageData
3043 **niClone = *niSrc;
3044 len = (*niClone)->nim_Width * (*niClone)->nim_Height;
3045 (*niClone)->nim_Palette = NULL;
3047 (*niClone)->nim_ImageData = MyAllocVecPooled(len);
3048 d1(KPrintF("%s/%s/%ld: nim_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, (*niClone)->nim_ImageData));
3049 if (NULL == (*niClone)->nim_ImageData)
3050 break;
3052 memcpy((*niClone)->nim_ImageData, niSrc->nim_ImageData, len);
3055 if (niSrc->nim_Palette)
3057 // Clone nim_Palette
3058 len = niSrc->nim_PaletteSize * sizeof(struct ColorRegister);
3060 (*niClone)->nim_Palette = MyAllocVecPooled(len);
3061 d1(KPrintF("%s/%s/%ld: nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, (*niClone)->nim_Palette));
3063 if (NULL == (*niClone)->nim_Palette)
3064 break;
3066 memcpy((*niClone)->nim_Palette, niSrc->nim_Palette, len);
3069 Success = TRUE;
3071 else
3073 *niClone = NULL;
3074 Success = TRUE;
3076 } while (0);
3078 if (*niClone && !Success)
3080 // Free partially allocated clone
3081 FreeNewImage(niClone);
3084 return Success;
3087 //----------------------------------------------------------------------------------------
3088 // EncodeData() based on ModifyIcon source by Dirk Stöcker
3089 //----------------------------------------------------------------------------------------
3091 static UBYTE *EncodeData(ULONG Depth, UWORD *DestLength,
3092 ULONG SrcLength, const UBYTE *SrcData)
3094 int i, j, k;
3095 ULONG bitbuf, numbits;
3096 UBYTE *buf;
3097 LONG ressize, numcopy, numequal;
3099 buf = MyAllocVecPooled(SrcLength * 2);
3100 if (NULL == buf)
3101 return NULL;
3103 numcopy = 0;
3104 numequal = 1;
3105 bitbuf = 0;
3106 numbits = 0;
3107 ressize = 0;
3108 k = 0; /* the real output pointer */
3110 for (i = 1; (numequal || numcopy) && (ressize < SrcLength);)
3112 if (i < SrcLength && numequal && (SrcData[i-1] == SrcData[i]))
3114 ++numequal;
3115 ++i;
3117 else if (i < SrcLength && numequal * Depth <= 16)
3119 numcopy += numequal;
3120 numequal = 1;
3121 ++i;
3123 else
3125 /* care for end case, where it maybe better to join the two */
3126 if (i == SrcLength && numcopy + numequal <= 128 && (numequal-1) * Depth <= 8)
3128 numcopy += numequal;
3129 numequal = 0;
3132 if (numcopy)
3134 if ((j = numcopy) > 128)
3135 j = 128;
3137 bitbuf = (bitbuf<<8) | (j-1);
3138 numcopy -= j;
3140 else
3142 if ((j = numequal) > 128)
3143 j = 128;
3145 bitbuf = (bitbuf<<8) | (256-(j-1));
3146 numequal -= j;
3147 k += j-1;
3148 j = 1;
3151 buf[ressize++] = (bitbuf >> numbits);
3153 while (j--)
3155 numbits += Depth;
3156 bitbuf = (bitbuf << Depth) | SrcData[k++];
3158 if (numbits >= 8)
3160 numbits -= 8;
3161 buf[ressize++] = (bitbuf >> numbits);
3165 if (i < SrcLength && !numcopy && !numequal)
3167 numequal = 1;
3168 ++i;
3173 if (numbits)
3174 buf[ressize++] = bitbuf << (8-numbits);
3176 if (ressize >= SrcLength)
3178 // no RLE
3179 ressize = SrcLength;
3180 CopyMem((APTR) SrcData, buf, SrcLength);
3183 *DestLength = ressize;
3185 return buf;
3188 //----------------------------------------------------------------------------------------
3190 static UBYTE INLINE GetNextDestByte(const UBYTE **src, size_t *SrcLength, short *srcBits,
3191 UBYTE *srcByte, LONG BitsPerEntry)
3193 UBYTE Mask;
3194 short destBits;
3195 short Shift;
3196 UBYTE Result = 0;
3198 destBits = 0;
3199 Mask = (1 << BitsPerEntry) - 1;
3200 Shift = 8 - BitsPerEntry - *srcBits;
3202 d1(kprintf("%s/%s/%ld: Shift=%ld BitsPerEntry=%ld Mask=%02lx\n", \
3203 __FILE__, __FUNC__, __LINE__, Shift, BitsPerEntry, Mask));
3205 while (destBits < BitsPerEntry)
3207 if (Shift < 0)
3209 d1(kprintf("%s/%s/%ld: (1) srcByte=%02lx sMask=%02lx Shift=%ld\n", \
3210 __FILE__, __FUNC__, __LINE__, *srcByte, (Mask >> -Shift), Shift));
3212 Result |= (*srcByte & (Mask >> -Shift)) << -Shift;
3213 destBits += BitsPerEntry + Shift;
3214 *srcBits += BitsPerEntry + Shift;
3215 Shift += 8;
3217 else
3219 d1(kprintf("%s/%s/%ld: (2) srcByte=%ld sMask=%02lx Shift=%ld\n", \
3220 __FILE__, __FUNC__, __LINE__, *srcByte, (Mask << Shift), Shift));
3222 Result |= (*srcByte & (Mask << Shift)) >> Shift;
3224 if (Shift + BitsPerEntry > 8)
3226 destBits += 8 - Shift;
3227 *srcBits += 8 - Shift;
3229 else
3231 destBits += BitsPerEntry;
3232 *srcBits += BitsPerEntry;
3235 Shift -= BitsPerEntry;
3236 if (Shift <= -BitsPerEntry)
3237 Shift += 8;
3240 d1(kprintf("%s/%s/%ld: Result = %02lx\n", __FILE__, __FUNC__, __LINE__, Result));
3242 if (*SrcLength && *srcBits >= 8)
3244 *srcBits %= 8;
3245 (*src)++;
3246 (*SrcLength)--;
3247 *srcByte = **src;
3252 d1(kprintf("%s/%s/%ld: srcBits=%ld destBits=%ld SrcByte=%02lx Result=%02lx\n", \
3253 __FILE__, __FUNC__, __LINE__, *srcBits, destBits, *srcByte, Result));
3255 return Result;
3258 //----------------------------------------------------------------------------------------
3260 static BOOL DecodeData(const UBYTE *src, UBYTE *dest, size_t SrcLength, size_t DestLength, LONG BitsPerEntry)
3262 short srcBits;
3263 signed char Rep = 0;
3264 short RepeatCount = 0;
3265 UBYTE RepeatByte = 0;
3266 UBYTE srcByte;
3268 srcByte = *src;
3269 srcBits = 0;
3271 while (DestLength)
3273 d1(KPrintF("%s/%s/%ld: DestLength=%ld in=%02lx out=%02lx\n",\
3274 __FILE__, __FUNC__, __LINE__, DestLength, srcByte, *dest));
3276 if (0 == RepeatCount)
3278 Rep = GetNextDestByte(&src, &SrcLength, &srcBits, &srcByte, 8);
3280 if (Rep < 0)
3282 RepeatCount = 1 - Rep;
3283 RepeatByte = GetNextDestByte(&src, &SrcLength, &srcBits, &srcByte, BitsPerEntry);
3285 else
3286 RepeatCount = 1 + Rep;
3288 d1(kprintf("%s/%s/%ld: Rep=%02lx RepeatCount=%ld RepeatByte=%02lx\n", \
3289 __FILE__, __FUNC__, __LINE__, Rep & 0xff, RepeatCount, RepeatByte));
3292 if (Rep >= 0)
3293 *dest++ = GetNextDestByte(&src, &SrcLength, &srcBits, &srcByte, BitsPerEntry);
3294 else
3295 *dest++ = RepeatByte;
3297 RepeatCount--;
3298 DestLength--;
3301 d1(KPrintF("%s/%s/%ld: END SrcLength=%lu DestLength=%lu\n", __FILE__, __FUNC__, __LINE__, SrcLength, DestLength));
3303 return (BOOL) (0 == DestLength && 0 == SrcLength);
3306 //----------------------------------------------------------------------------------------
3308 static UBYTE *GenerateMask(struct NewImage *nim)
3310 ULONG Size;
3311 UBYTE *MaskArray;
3312 ULONG BytesPerRow;
3314 d1(KPrintF("%s/%s/%ld: ic_Flags=%02lx ic_TransparentColor=%ld\n", \
3315 __FILE__, __FUNC__, __LINE__, nim->nim_ImageChunk.ic_Flags, nim->nim_ImageChunk.ic_TransparentColor));
3317 BytesPerRow = BYTESPERROW(nim->nim_Width);
3318 Size = nim->nim_Height * BytesPerRow;
3319 MaskArray = MyAllocVecPooled(Size);
3320 if (MaskArray)
3322 if (nim->nim_ImageChunk.ic_Flags & ICF_IsTransparent)
3324 const UBYTE *ChunkyData = nim->nim_ImageData;
3325 UBYTE *MaskPtr = MaskArray;
3326 ULONG y;
3328 memset(MaskArray, 0, Size);
3330 for (y = 0; y < nim->nim_Height; y++)
3332 ULONG x;
3333 UBYTE BitMask = 0x80;
3334 UBYTE *MaskPtr2 = MaskPtr;
3336 for (x = 0; x < nim->nim_Width; x++)
3338 if (nim->nim_ImageChunk.ic_TransparentColor != *ChunkyData++)
3339 *MaskPtr2 |= BitMask;
3340 BitMask >>= 1;
3341 if (0 == BitMask)
3343 BitMask = 0x80;
3344 MaskPtr2++;
3348 MaskPtr += BytesPerRow;
3351 else
3353 memset(MaskArray, ~0, Size);
3357 return MaskArray;
3360 //----------------------------------------------------------------------------------------
3362 static APTR MyAllocVecPooled(size_t Size)
3364 APTR ptr;
3366 if (MemPool)
3368 ObtainSemaphore(&PubMemPoolSemaphore);
3369 ptr = AllocPooled(MemPool, Size + sizeof(size_t));
3370 ReleaseSemaphore(&PubMemPoolSemaphore);
3371 if (ptr)
3373 size_t *sptr = (size_t *) ptr;
3375 sptr[0] = Size;
3377 d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", \
3378 __FILE__, __FUNC__, __LINE__, MemPool, Size, &sptr[1]));
3379 return (APTR)(&sptr[1]);
3383 d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, MemPool, Size));
3385 return NULL;
3389 static void MyFreeVecPooled(APTR mem)
3391 d1(kprintf("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, mem));
3392 if (MemPool && mem)
3394 size_t size;
3395 size_t *sptr = (size_t *) mem;
3397 mem = &sptr[-1];
3398 size = sptr[-1];
3400 ObtainSemaphore(&PubMemPoolSemaphore);
3401 FreePooled(MemPool, mem, size + sizeof(size_t));
3402 ReleaseSemaphore(&PubMemPoolSemaphore);
3406 //----------------------------------------------------------------------------------------
3408 static struct NewImage *NewImageFromSAC(struct ScalosBitMapAndColor *sac)
3410 struct NewImage *ni = NULL;
3411 struct BitMap *TempBM;
3412 BOOL Success = FALSE;
3414 do {
3415 ULONG n;
3416 ULONG y;
3417 const ULONG *PalettePtr;
3418 struct RastPort rp;
3419 struct RastPort TempRp;
3420 UBYTE *ImagePtr;
3421 ULONG NewWidth = sac->sac_Width;
3422 ULONG NewHeight = sac->sac_Height;
3424 InitRastPort(&rp);
3425 InitRastPort(&TempRp);
3427 rp.BitMap = sac->sac_BitMap;
3428 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: rp.BitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, rp.BitMap));
3430 // setup temp. RastPort for use by WritePixelLine8()
3431 TempRp.Layer = NULL;
3432 TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(NewWidth), 1, 8, 0, NULL);
3434 if (NULL == TempBM)
3435 break;
3436 ni = MyAllocVecPooled(sizeof(struct NewImage));
3437 if (NULL == ni)
3438 break;
3440 memset(ni, 0, sizeof(struct NewImage));
3442 ni->nim_Width = NewWidth;
3443 ni->nim_Height = NewHeight;
3445 ni->nim_ImageChunk.ic_TransparentColor = sac->sac_TransparentColor;
3446 ni->nim_ImageChunk.ic_Flags |= ICF_HasPalette;
3447 if (SAC_TRANSPARENT_NONE != sac->sac_TransparentColor)
3448 ni->nim_ImageChunk.ic_Flags |= ICF_IsTransparent;
3450 d1(KPrintF(__FILE__ "/" "%s/%s/%ld: sac_TransparentColor=%ld\n", __FILE__, __FUNC__, __LINE__, sac->sac_TransparentColor));
3452 ni->nim_ImageChunk.ic_PaletteSize = sac->sac_NumColors - 1;
3453 ni->nim_ImageChunk.ic_BitsPerPixel = sac->sac_Depth;
3455 ni->nim_ImageData = MyAllocVecPooled(PIXELARRAY8_BUFFERSIZE(ni->nim_Width, ni->nim_Height));
3456 if (NULL == ni->nim_ImageData)
3457 break;
3459 ni->nim_PaletteSize = sac->sac_NumColors;
3460 ni->nim_Palette = MyAllocVecPooled(sac->sac_NumColors * sizeof(struct ColorRegister));
3461 if (NULL == ni->nim_Palette)
3462 break;
3464 // nothing can go wrong from here on
3465 Success = TRUE;
3467 d1(KPrintF("%s/%s/%ld: NumColors=%lu\n", __FILE__, __FUNC__, __LINE__, sac->sac_NumColors));
3469 // Fill nim_Palette fom sac_ColorTable
3470 for (n = 0, PalettePtr = sac->sac_ColorTable; n < sac->sac_NumColors; n++)
3472 ni->nim_Palette[n].red = *PalettePtr++ >> 24;
3473 ni->nim_Palette[n].green = *PalettePtr++ >> 24;
3474 ni->nim_Palette[n].blue = *PalettePtr++ >> 24;
3477 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
3479 // copy image data from sac_BitMap into nim_ImageData
3480 for (y = 0, ImagePtr = ni->nim_ImageData; y < NewHeight; y++)
3482 d1(KPrintF("%s/%s/%ld: y=%ld\n", __FILE__, __FUNC__, __LINE__, y));
3483 ReadPixelLine8(&rp, 0, y, NewWidth,
3484 ImagePtr, &TempRp);
3485 ImagePtr += NewWidth;
3488 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
3489 } while (0);
3491 if (!Success)
3492 FreeNewImage(&ni);
3494 if (TempBM)
3495 FreeBitMap(TempBM);
3497 return ni;
3500 //----------------------------------------------------------------------------------------
3502 static void GenerateNormalImageMask(Class *cl, Object *o)
3504 struct InstanceData *inst = INST_DATA(cl, o);
3505 UBYTE *MaskNormal = NULL;
3507 if (inst->aio_Image1->nim_ImageChunk.ic_Flags & ICF_IsTransparent)
3509 MaskNormal = GenerateMask(inst->aio_Image1);
3512 d1(KPrintF("%s/%s/%ld: MaskNormal=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskNormal));
3514 SetAttrs(o, IDTA_Mask_Normal, (ULONG) MaskNormal,
3515 IDTA_Width_Mask_Normal, inst->aio_Image1->nim_Width,
3516 IDTA_Height_Mask_Normal, inst->aio_Image1->nim_Height,
3517 TAG_END);
3519 if (MaskNormal)
3520 MyFreeVecPooled(MaskNormal);
3523 //----------------------------------------------------------------------------------------
3525 static void GenerateSelectedImageMask(Class *cl, Object *o)
3527 struct InstanceData *inst = INST_DATA(cl, o);
3528 UBYTE *MaskSelected = NULL;
3530 if (inst->aio_Image2 && (inst->aio_Image2->nim_ImageChunk.ic_Flags & ICF_IsTransparent))
3532 MaskSelected = GenerateMask(inst->aio_Image2);
3535 d1(KPrintF("%s/%s/%ld: MaskSelected=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskSelected));
3537 SetAttrs(o, IDTA_Mask_Selected, (ULONG) MaskSelected,
3538 IDTA_Width_Mask_Selected, inst->aio_Image2->nim_Width,
3539 IDTA_Height_Mask_Selected, inst->aio_Image2->nim_Height,
3540 TAG_END);
3542 if (MaskSelected)
3543 MyFreeVecPooled(MaskSelected);
3546 //----------------------------------------------------------------------------------------
3548 static struct NewImage *NewImageFromNormalImage(const struct InstanceData *inst, const struct NewImage *niNormal)
3550 struct NewImage *ni = NULL;
3551 BOOL Success = FALSE;
3553 d1(KPrintF("%s/%s/%ld: inst=%08lx, niNormal=%08lx\n", __FILE__, __FUNC__, __LINE__, inst, niNormal));
3555 do {
3556 ULONG n;
3557 const struct ColorRegister *PaletteSrcPtr;
3558 struct ColorRegister *PaletteDestPtr;
3559 size_t ImgSize;
3560 ULONG Backfill[2] = { IDTA_BACKFILL_NONE, IDTA_BACKFILL_NONE };
3561 ULONG BackfillCount = 0;
3563 ni = MyAllocVecPooled(sizeof(struct NewImage));
3564 if (NULL == ni)
3565 break;
3567 memset(ni, 0, sizeof(struct NewImage));
3569 ni->nim_Width = niNormal->nim_Width;
3570 ni->nim_Height = niNormal->nim_Height;
3572 ImgSize = ni->nim_Width * ni->nim_Height;
3574 ni->nim_ImageChunk.ic_TransparentColor = niNormal->nim_ImageChunk.ic_TransparentColor;
3575 ni->nim_ImageChunk.ic_Flags = niNormal->nim_ImageChunk.ic_Flags;
3577 d1(KPrintF("%s/%s/%ld: ic_TransparentColor=%ld\n", __FILE__, __FUNC__, __LINE__, ni->nim_ImageChunk.ic_TransparentColor));
3578 d1(KPrintF("%s/%s/%ld: ic_PaletteSize=%lu\n", __FILE__, __FUNC__, __LINE__, niNormal->nim_ImageChunk.ic_PaletteSize));
3580 ni->nim_ImageChunk.ic_PaletteSize = niNormal->nim_ImageChunk.ic_PaletteSize;
3581 ni->nim_ImageChunk.ic_BitsPerPixel = niNormal->nim_ImageChunk.ic_BitsPerPixel;
3583 ni->nim_ImageData = MyAllocVecPooled(ImgSize);
3584 if (NULL == ni->nim_ImageData)
3585 break;
3587 ni->nim_PaletteSize = niNormal->nim_PaletteSize;
3589 if (niNormal->nim_Palette)
3591 ni->nim_Palette = MyAllocVecPooled(ni->nim_PaletteSize * sizeof(struct ColorRegister));
3592 if (NULL == ni->nim_Palette)
3593 break;
3595 // nothing can go wrong from here on
3596 Success = TRUE;
3598 // remember color table indices for backfill colors
3599 if (IDTA_BACKFILL_NONE != inst->aio_BackfillPenSel)
3600 Backfill[BackfillCount++] = ni->nim_PaletteSize - 1;
3601 if (IDTA_BACKFILL_NONE != inst->aio_BackfillPenNorm)
3602 Backfill[BackfillCount] = ni->nim_PaletteSize - 2;
3604 d1(KPrintF("%s/%s/%ld: nim_PaletteSize=%lu aio_BackfillPenNorm=%ld aio_BackfillPenSel=%ld\n", \
3605 __FILE__, __FUNC__, __LINE__, ni->nim_PaletteSize, inst->aio_BackfillPenNorm, inst->aio_BackfillPenSel));
3607 // copy palette from niNormal and adjust colors
3608 for (n = 0, PaletteSrcPtr = niNormal->nim_Palette, PaletteDestPtr = ni->nim_Palette;
3609 n < ni->nim_PaletteSize; n++)
3611 if (n == Backfill[0] || n == Backfill[1])
3613 // do not modify backfill colors
3614 *PaletteDestPtr = *PaletteSrcPtr;
3616 else
3618 PaletteDestPtr->red = (2 * PaletteSrcPtr->red) / 3;
3619 PaletteDestPtr->green = (2 * PaletteSrcPtr->green) / 3;
3620 PaletteDestPtr->blue = (2 * PaletteSrcPtr->blue) / 3;
3622 PaletteDestPtr++;
3623 PaletteSrcPtr++;
3626 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
3628 // copy image data from niNormal into nim_ImageData
3629 memcpy(ni->nim_ImageData, niNormal->nim_ImageData, ImgSize);
3631 else
3633 // we have no palette
3634 // 32bit GlowIcon
3635 size_t ISize = niNormal->nim_ARGBheader.argb_Width * niNormal->nim_ARGBheader.argb_Height;
3636 const struct ARGB *Src;
3637 struct ARGB *Dest;
3639 ni->nim_ARGBheader.argb_Width = niNormal->nim_ARGBheader.argb_Width;
3640 ni->nim_ARGBheader.argb_Height = niNormal->nim_ARGBheader.argb_Height;
3642 ni->nim_ARGBheader.argb_ImageData = MyAllocVecPooled(ISize * sizeof(struct ARGB));
3644 d1(KPrintF("%s/%s/%ld: ISize=%lu argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, ISize, ni->nim_ARGBheader.argb_ImageData));
3645 if (NULL == ni->nim_ARGBheader.argb_ImageData)
3646 break;
3648 // nothing can go wrong from here on
3649 Success = TRUE;
3651 // Copy image data and adjust RGB values
3652 Src = niNormal->nim_ARGBheader.argb_ImageData;
3653 Dest = ni->nim_ARGBheader.argb_ImageData;
3654 for (n = 0; n < ISize; n++, Src++, Dest++)
3656 Dest->Red = (2 * Src->Red ) / 3;
3657 Dest->Green = (2 * Src->Green) / 3;
3658 Dest->Blue = (2 * Src->Blue ) / 3;
3659 Dest->Alpha = Src->Alpha;
3663 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
3664 } while (0);
3666 if (!Success)
3667 FreeNewImage(&ni);
3669 d1(KPrintF("%s/%s/%ld: ni=%08lx\n", __FILE__, __FUNC__, __LINE__, ni));
3671 return ni;
3674 //----------------------------------------------------------------------------------------
3676 static void *ZLibAlloc(void *p, int items, int size)
3678 return MyAllocVecPooled(items * size);
3682 static void ZLibFree(void *p, void *addr)
3684 MyFreeVecPooled(addr);
3687 //----------------------------------------------------------------------------------------
3689 static SAVEDS(LONG) StreamHookDispatcher(struct Hook *hook, struct IFFHandle *iff, const struct IFFStreamCmd *cmd)
3691 LONG Result = 0;
3693 switch (cmd->sc_Command)
3695 case IFFCMD_INIT:
3696 /* Prepare your stream for reading. This is used for certain
3697 streams that can't be read immediately upon opening, and need
3698 further preparation. (The clipboard.device is an example of
3699 such a stream.) This operation is allowed to fail; any
3700 error code will be returned directly to the client. sc_Buf
3701 and sc_NBytes have no meaning here. */
3702 break;
3703 case IFFCMD_CLEANUP:
3704 /* Terminate the transaction with the associated stream. This
3705 is used with streams that can't simply be closed. (Again,
3706 the clipboard is an example of such a stream.) This
3707 operation is not permitted to fail; any error returned will
3708 be ignored (best to return 0, though). sc_Buf and sc_NBytes
3709 have no meaning here. */
3710 break;
3711 case IFFCMD_READ:
3712 /* Read from the stream. You are to read sc_NBytes from the
3713 stream and place them in the buffer pointed to by sc_Buf.
3714 Any (non-zero) error returned will be remapped by the parser
3715 into IFFERR_READ. */
3716 if (1 != FRead((BPTR)iff->iff_Stream, cmd->sc_Buf, cmd->sc_NBytes, 1))
3717 Result = IFFERR_READ;
3718 break;
3719 case IFFCMD_WRITE:
3720 /* Write to the stream. You are to write sc_NBytes to the
3721 stream from the buffer pointed to by sc_Buf. Any (non-zero)
3722 error returned will be remapped by the parser into
3723 IFFERR_WRITE. */
3724 if (1 != FWrite((BPTR)iff->iff_Stream, cmd->sc_Buf, cmd->sc_NBytes, 1))
3725 Result = IFFERR_WRITE;
3726 d1(KPrintF("%s/%s/%ld: IFFCMD_WRITE Result=%ld sc_NBytes=%ld\n", __FILE__, __FUNC__, __LINE__, Result, cmd->sc_NBytes));
3727 break;
3728 case IFFCMD_SEEK:
3729 /* Seek on the stream. You are to perform a seek on the stream
3730 relative to the current position. sc_NBytes is signed;
3731 negative values mean seek backward, positive values mean seek
3732 forward. sc_Buf has no meaning here. Any (non-zero) error
3733 returned will be remapped by the parser into IFFERR_SEEK. */
3734 if (Seek((BPTR)iff->iff_Stream, cmd->sc_NBytes, OFFSET_CURRENT) < 0)
3735 Result = IFFERR_SEEK;
3736 d1(KPrintF("%s/%s/%ld: IFFCMD_SEEK Result=%ld sc_NBytes=%ld\n", __FILE__, __FUNC__, __LINE__, Result, cmd->sc_NBytes));
3737 break;
3738 default:
3739 break;
3742 return Result;
3745 //----------------------------------------------------------------------------------------
3747 static void SetParentAttributes(Class *cl, Object *o)
3749 struct InstanceData *inst = INST_DATA(cl, o);
3751 TIMESTAMP_d1();
3752 SetAttrs(o,
3753 GA_Width, inst->aio_Image1->nim_Width,
3754 GA_Height, inst->aio_Image1->nim_Height,
3755 TAG_END);
3756 d1(KPrintF("%s/%s/%ld: o=%08lx Image1 nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_Image1->nim_Palette));
3758 if (NULL == inst->aio_Image1->nim_Palette)
3760 // 32bit GlowIcon
3761 SetAttrs(o,
3762 IDTA_CopyARGBImageData, FALSE,
3763 IDTA_ARGBImageData, (ULONG) &inst->aio_Image1->nim_ARGBheader,
3764 TAG_END);
3766 TIMESTAMP_d1();
3767 if (inst->aio_Image2 && NULL == inst->aio_Image2->nim_Palette)
3769 // 32bit GlowIcon
3770 SetAttrs(o,
3771 IDTA_CopySelARGBImageData, FALSE,
3772 IDTA_SelARGBImageData, (ULONG) &inst->aio_Image2->nim_ARGBheader,
3773 TAG_END);
3776 if (inst->aio_Image1->nim_Palette)
3778 TIMESTAMP_d1();
3779 GenerateNormalImageMask(cl, o);
3780 TIMESTAMP_d1();
3781 GenerateSelectedImageMask(cl, o);
3782 TIMESTAMP_d1();
3785 TIMESTAMP_d1();
3787 if (inst->aio_DiskObject->do_DrawerData)
3789 TIMESTAMP_d1();
3790 SetAttrs(o,
3791 IDTA_ViewModes, inst->aio_DiskObject->do_DrawerData->dd_ViewModes,
3792 IDTA_Flags, inst->aio_DiskObject->do_DrawerData->dd_Flags,
3793 IDTA_WinCurrentX, inst->aio_DiskObject->do_DrawerData->dd_CurrentX,
3794 IDTA_WinCurrentY, inst->aio_DiskObject->do_DrawerData->dd_CurrentY,
3795 IDTA_WindowRect, (ULONG) &inst->aio_DiskObject->do_DrawerData->dd_NewWindow,
3796 TAG_END);
3798 TIMESTAMP_d1();
3799 SetAttrs(o,
3800 IDTA_ToolTypes, (ULONG) inst->aio_DiskObject->do_ToolTypes,
3801 IDTA_Stacksize, inst->aio_DiskObject->do_StackSize,
3802 IDTA_DefaultTool, (ULONG) inst->aio_DiskObject->do_DefaultTool,
3803 IDTA_Type, inst->aio_DiskObject->do_Type,
3804 IDTA_Borderless, inst->aio_Borderless,
3805 TAG_END);
3808 //----------------------------------------------------------------------------------------
3810 #if defined(__AROS__)
3811 static BOOL ReadConvertStandardIcon(BPTR fd, struct DiskObject *dobj)
3813 BOOL success = FALSE;
3815 APTR block = MyAllocVecPooled(78); // sizeof struct DiskObject on 68k
3816 if (NULL != block)
3818 if (78 == FRead(fd, block, 1, 78))
3820 dobj->do_Magic = SCA_BE2WORD(*(WORD *)block);
3821 dobj->do_Version = SCA_BE2WORD(*(WORD *)(block + 2));
3822 // Ignore 4
3823 dobj->do_Gadget.LeftEdge = SCA_BE2WORD(*(WORD *)(block + 8));
3824 dobj->do_Gadget.TopEdge = SCA_BE2WORD(*(WORD *)(block + 10));
3825 dobj->do_Gadget.Width = SCA_BE2WORD(*(WORD *)(block + 12));
3826 dobj->do_Gadget.Height = SCA_BE2WORD(*(WORD *)(block + 14));
3827 dobj->do_Gadget.Flags = SCA_BE2WORD(*(WORD *)(block + 16));
3828 dobj->do_Gadget.Activation = SCA_BE2WORD(*(WORD *)(block + 18));
3829 dobj->do_Gadget.GadgetType = SCA_BE2WORD(*(WORD *)(block + 20));
3830 dobj->do_Gadget.GadgetRender = (APTR)SCA_BE2LONG(*(LONG *)(block + 22));
3831 dobj->do_Gadget.SelectRender = (APTR)SCA_BE2LONG(*(LONG *)(block + 26));
3832 dobj->do_Gadget.GadgetText = (APTR)SCA_BE2LONG(*(LONG *)(block + 30));
3833 dobj->do_Gadget.MutualExclude = SCA_BE2LONG(*(LONG *)(block + 34));
3834 dobj->do_Gadget.SpecialInfo = (APTR)SCA_BE2LONG(*(LONG *)(block + 38));
3835 dobj->do_Gadget.GadgetID = SCA_BE2WORD(*(WORD *)(block + 42));
3836 dobj->do_Gadget.UserData = (APTR)SCA_BE2LONG(*(LONG *)(block + 44));
3837 dobj->do_Type = *(BYTE *)(block + 48);
3838 // Ignore 1
3839 dobj->do_DefaultTool = (APTR)SCA_BE2LONG(*(LONG *)(block + 50));
3840 dobj->do_ToolTypes = (APTR)SCA_BE2LONG(*(LONG *)(block + 54));
3841 dobj->do_CurrentX = SCA_BE2LONG(*(LONG *)(block + 58));
3842 dobj->do_CurrentY = SCA_BE2LONG(*(LONG *)(block + 62));
3843 dobj->do_DrawerData = (APTR)SCA_BE2LONG(*(LONG *)(block + 66));
3844 dobj->do_ToolWindow = (APTR)SCA_BE2LONG(*(LONG *)(block + 70));
3845 dobj->do_StackSize = SCA_BE2LONG(*(LONG *)(block + 74));
3847 success = TRUE;
3849 MyFreeVecPooled(block);
3851 return success;
3854 //----------------------------------------------------------------------------------------
3856 static BOOL WriteConvertStandardIcon(BPTR fd, struct DiskObject *dobj)
3858 BOOL success = FALSE;
3860 APTR block = MyAllocVecPooled(78); // sizeof struct DiskObject on 68k
3861 if (NULL != block)
3863 memset(block, 0, 78);
3864 *(WORD *)block = SCA_WORD2BE(dobj->do_Magic);
3865 *(WORD *)(block + 2) = SCA_WORD2BE(dobj->do_Version);
3866 // Ignore 4
3867 *(WORD *)(block + 8) = SCA_WORD2BE(dobj->do_Gadget.LeftEdge);
3868 *(WORD *)(block + 10) = SCA_WORD2BE(dobj->do_Gadget.TopEdge);
3869 *(WORD *)(block + 12) = SCA_WORD2BE(dobj->do_Gadget.Width);
3870 *(WORD *)(block + 14) = SCA_WORD2BE(dobj->do_Gadget.Height);
3871 *(WORD *)(block + 16) = SCA_WORD2BE(dobj->do_Gadget.Flags);
3872 *(WORD *)(block + 18) = SCA_WORD2BE(dobj->do_Gadget.Activation);
3873 *(WORD *)(block + 20) = SCA_WORD2BE(dobj->do_Gadget.GadgetType);
3874 *(LONG *)(block + 22) = SCA_LONG2BE((LONG)dobj->do_Gadget.GadgetRender);
3875 *(LONG *)(block + 26) = SCA_LONG2BE((LONG)dobj->do_Gadget.SelectRender);
3876 *(LONG *)(block + 30) = SCA_LONG2BE((LONG)dobj->do_Gadget.GadgetText);
3877 *(LONG *)(block + 34) = SCA_LONG2BE(dobj->do_Gadget.MutualExclude);
3878 *(LONG *)(block + 38) = SCA_LONG2BE((LONG)dobj->do_Gadget.SpecialInfo);
3879 *(WORD *)(block + 42) = SCA_WORD2BE(dobj->do_Gadget.GadgetID);
3880 *(LONG *)(block + 44) = SCA_LONG2BE((LONG)dobj->do_Gadget.UserData);
3881 *(BYTE *)(block + 48) = dobj->do_Type;
3882 // Ignore 1
3883 *(LONG *)(block + 50) = SCA_LONG2BE((LONG)dobj->do_DefaultTool);
3884 *(LONG *)(block + 54) = SCA_LONG2BE((LONG)dobj->do_ToolTypes);
3885 *(LONG *)(block + 58) = SCA_LONG2BE(dobj->do_CurrentX);
3886 *(LONG *)(block + 62) = SCA_LONG2BE(dobj->do_CurrentY);
3887 *(LONG *)(block + 66) = SCA_LONG2BE((LONG)dobj->do_DrawerData);
3888 *(LONG *)(block + 70) = SCA_LONG2BE((LONG)dobj->do_ToolWindow);
3889 *(LONG *)(block + 74) = SCA_LONG2BE(dobj->do_StackSize);
3891 if (78 == FWrite(fd, block, 1, 78))
3892 success = TRUE;
3894 MyFreeVecPooled(block);
3896 return success;
3899 //----------------------------------------------------------------------------------------
3901 static BOOL ReadConvertDrawerData(BPTR fd, struct DrawerData *drawer)
3903 BOOL success = FALSE;
3905 APTR block = MyAllocVecPooled(56); // sizeof struct OldDrawerData on 68k
3906 if (NULL != block)
3908 if (56 == FRead(fd, block, 1, 56))
3910 drawer->dd_NewWindow.LeftEdge = SCA_BE2WORD(*(WORD *)block);
3911 drawer->dd_NewWindow.TopEdge = SCA_BE2WORD(*(WORD *)(block + 2));
3912 drawer->dd_NewWindow.Width = SCA_BE2WORD(*(WORD *)(block + 4));
3913 drawer->dd_NewWindow.Height = SCA_BE2WORD(*(WORD *)(block + 6));
3914 drawer->dd_NewWindow.DetailPen = *(BYTE *)(block + 8);
3915 drawer->dd_NewWindow.BlockPen = *(BYTE *)(block + 9);
3916 drawer->dd_NewWindow.IDCMPFlags = SCA_BE2LONG(*(LONG *)(block + 10));
3917 drawer->dd_NewWindow.Flags = SCA_BE2LONG(*(LONG *)(block + 14));
3918 // Ignore 20
3919 drawer->dd_NewWindow.MinWidth = SCA_BE2WORD(*(WORD *)(block + 38));
3920 drawer->dd_NewWindow.MinHeight = SCA_BE2WORD(*(WORD *)(block + 40));
3921 drawer->dd_NewWindow.MaxWidth = SCA_BE2WORD(*(WORD *)(block + 42));
3922 drawer->dd_NewWindow.MaxHeight = SCA_BE2WORD(*(WORD *)(block + 44));
3923 drawer->dd_NewWindow.Type = SCA_BE2WORD(*(WORD *)(block + 46));
3924 drawer->dd_CurrentX = SCA_BE2LONG(*(LONG *)(block + 48));
3925 drawer->dd_CurrentY = SCA_BE2LONG(*(LONG *)(block + 52));
3927 success = TRUE;
3929 MyFreeVecPooled(block);
3931 return success;
3934 //----------------------------------------------------------------------------------------
3936 static BOOL WriteConvertDrawerData(BPTR fd, struct DrawerData *drawer)
3938 BOOL success = FALSE;
3940 APTR block = MyAllocVecPooled(56); // sizeof struct OldDrawerData on 68k
3941 if (NULL != block)
3943 memset(block, 0, 56);
3944 *(WORD *)block = SCA_WORD2BE(drawer->dd_NewWindow.LeftEdge);
3945 *(WORD *)(block + 2) = SCA_WORD2BE(drawer->dd_NewWindow.TopEdge);
3946 *(WORD *)(block + 4) = SCA_WORD2BE(drawer->dd_NewWindow.Width);
3947 *(WORD *)(block + 6) = SCA_WORD2BE(drawer->dd_NewWindow.Height);
3948 *(BYTE *)(block + 8) = drawer->dd_NewWindow.DetailPen;
3949 *(BYTE *)(block + 9) = drawer->dd_NewWindow.BlockPen;
3950 *(LONG *)(block + 10) = SCA_LONG2BE(drawer->dd_NewWindow.IDCMPFlags);
3951 *(LONG *)(block + 14) = SCA_LONG2BE(drawer->dd_NewWindow.Flags);
3952 // Ignore 20
3953 *(WORD *)(block + 38) = SCA_WORD2BE(drawer->dd_NewWindow.MinWidth);
3954 *(WORD *)(block + 40) = SCA_WORD2BE(drawer->dd_NewWindow.MinHeight);
3955 *(WORD *)(block + 42) = SCA_WORD2BE(drawer->dd_NewWindow.MaxWidth);
3956 *(WORD *)(block + 44) = SCA_WORD2BE(drawer->dd_NewWindow.MaxHeight);
3957 *(WORD *)(block + 46) = SCA_WORD2BE(drawer->dd_NewWindow.Type);
3958 *(LONG *)(block + 48) = SCA_LONG2BE(drawer->dd_CurrentX);
3959 *(LONG *)(block + 52) = SCA_LONG2BE(drawer->dd_CurrentY);
3961 if (56 == FWrite(fd, block, 1, 56))
3962 success = TRUE;
3964 MyFreeVecPooled(block);
3966 return success;
3969 //----------------------------------------------------------------------------------------
3971 static BOOL ReadConvertImage(BPTR fd, struct Image *img)
3973 BOOL success = FALSE;
3975 APTR block = MyAllocVecPooled(20); // sizeof struct Image on 68k
3976 if (NULL != block)
3978 if (20 == FRead(fd, block, 1, 20))
3980 img->LeftEdge = SCA_BE2WORD(*(WORD *)block);
3981 img->TopEdge = SCA_BE2WORD(*(WORD *)(block + 2));
3982 img->Width = SCA_BE2WORD(*(WORD *)(block + 4));
3983 img->Height = SCA_BE2WORD(*(WORD *)(block + 6));
3984 img->Depth = SCA_BE2WORD(*(WORD *)(block + 8));
3985 img->ImageData = (APTR)SCA_BE2LONG(*(LONG *)(block + 10));
3986 img->PlanePick = *(BYTE *)(block + 14);
3987 img->PlaneOnOff = *(BYTE *)(block + 15);
3988 img->NextImage = (APTR)SCA_BE2LONG(*(LONG *)(block + 16));
3990 success = TRUE;
3993 MyFreeVecPooled(block);
3996 return success;
3999 //----------------------------------------------------------------------------------------
4001 static BOOL WriteConvertImage(BPTR fd, struct Image *img)
4003 BOOL success = FALSE;
4005 APTR block = MyAllocVecPooled(20); // sizeof struct Image on 68k
4006 if (NULL != block)
4008 memset(block, 0, 20);
4009 *(WORD *)block = SCA_WORD2BE(img->LeftEdge);
4010 *(WORD *)(block + 2) = SCA_WORD2BE(img->TopEdge) ;
4011 *(WORD *)(block + 4) = SCA_WORD2BE(img->Width);
4012 *(WORD *)(block + 6) = SCA_WORD2BE(img->Height);
4013 *(WORD *)(block + 8) = SCA_WORD2BE(img->Depth);
4014 *(LONG *)(block + 10) = SCA_LONG2BE((LONG)img->ImageData);
4015 *(BYTE *)(block + 14) = img->PlanePick;
4016 *(BYTE *)(block + 15) = img->PlaneOnOff;
4017 *(LONG *)(block + 16) = SCA_LONG2BE((LONG)img->NextImage);
4019 if (20 == FWrite(fd, block, 1, 20))
4020 success = TRUE;
4022 MyFreeVecPooled(block);
4024 return success;
4026 #endif
4028 //----------------------------------------------------------------------------------------
4030 #ifndef __amigaos4__
4031 void exit(int x)
4033 (void) x;
4034 while (1)
4037 #endif /* __amigaos4__ */
4039 //----------------------------------------------------------------------------------------