about summary refs log tree commit diff
path: root/converter/other/infotopam.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other/infotopam.c')
-rw-r--r--converter/other/infotopam.c150
1 files changed, 143 insertions, 7 deletions
diff --git a/converter/other/infotopam.c b/converter/other/infotopam.c
index bb7d2e74..e9ce4d04 100644
--- a/converter/other/infotopam.c
+++ b/converter/other/infotopam.c
@@ -45,9 +45,128 @@
  * bit-plane, and '0' is padding.  Thanks again to Ben Hutchings for his
  * very helpful post!
  *
- * This program uses code from "sidplay" and an older "infotoxpm" program I
- * wrote, both of which are released under GPL.
+ *-----------------------------------------------------------------------------
+ * The following specification for the DiskObject header is from
+ * http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node0241.html
+ * on 2024.03.14.
  *
+ * The DiskObject C structure is defined in the include file
+ * <workbench/workbench.h>.  For a complete listing, see the Amiga ROM Kernel
+ * Reference Manual: Includes and Autodocs.  The DiskObject structure contains
+ * the following elements:
+ *
+ *     struct DiskObject {
+ *         UWORD              do_Magic;    magic number at start of file
+ *         UWORD              do_Version;  so we can change structure
+ *         struct Gadget      do_Gadget;   a copy of in core gadget
+ *         UBYTE              do_Type;
+ *         char              *do_DefaultTool;
+ *         char             **do_ToolTypes;
+ *         LONG               do_CurrentX;
+ *         LONG               do_CurrentY;
+ *         struct DrawerData *do_DrawerData;
+ *         char              *do_ToolWindow;  applies only to tools
+ *         LONG               do_StackSize;   applies only to tools
+ *     };
+ *
+ * do_Magic
+ *
+ *     A magic number that the icon library looks for to make sure that the
+ *     file it is reading really contains an icon.  It should be the manifest
+ *     constant WB_DISKMAGIC.  PutDiskObject() will put this value in the
+ *     structure, and GetDiskObject() will not believe that a file is really
+ *     an icon unless this value is correct.
+ *
+ * do_Version
+ *
+ *     This provides a way to enhance the .info file in an upwardly-compatible
+ *     way.  It should be WB_DISKVERSION.  The icon library will set this value
+ *     for you and will not believe weird values.
+ *
+ * do_Gadget
+ *
+ *     This contains all the imagery for the icon. See the "Gadget Structure"
+ *     section below for more details.
+ *
+ * do_Type
+ *
+ *     The type of the icon; can be set to any of the following values.
+ *
+ *         WBDISK     The root of a disk
+ *         WBDRAWER   A directory on the disk
+ *         WBTOOL     An executable program
+ *         WBPROJECT  A data file
+ *         WBGARBAGE  The Trashcan directory
+ *         WBKICK     A Kickstart disk
+ *         WBAPPICON  Any object not directly associated with a filing system
+ *                    object, such as a print spooler (new in Release 2).
+ *
+ * do_DefaultTool
+ *
+ *     Default tools are used for project and disk icons.  For projects (data
+ *     files), the default tool is the program Workbench runs when the project
+ *     is activated.  Any valid AmigaDOS path may be entered in this field
+ *     such as "SYS:myprogram", "df0:mypaint", "myeditor" or ":work/mytool".
+ *
+ *     For disk icons, the default tool is the diskcopy program
+ *     ("SYS:System/DiskCopy") that will be used when this disk is the source
+ *     of a copy.
+ *
+ * do_ToolTypes
+ *
+ *     This is an array of free-format strings.  Workbench does not enforce
+ *     any rules on these strings, but they are useful for passing
+ *     environment information.  See the section on "The Tool Types Array"
+ *     below for more information.
+ *
+ * do_CurrentX, do_CurrentY
+ *
+ *     Drawers have a virtual coordinate system.  The user can scroll around
+ *     in this system using the scroll gadgets on the window that opens when
+ *     the drawer is activated.  Each icon in the drawer has a position in
+ *     the coordinate system.  CurrentX and CurrentY contain the icon's
+ *     current position in the drawer.  Picking a position for a newly
+ *     created icon can be tricky.  NO_ICON_POSITION is a system constant
+ *     for do_CurrentX and do_CurrentY that instructs Workbench to pick a
+ *     reasonable place for the icon.  Workbench will place the icon in an
+ *     unused region of the drawer.  If there is no space in the drawers
+ *     window, the icon will be placed just to the right of the visible
+ *     region.
+ *
+ * do_DrawerData
+ *
+ *     If the icon is associated with a directory (WBDISK, WBDRAWER,
+ *     WBGARBAGE), it needs a DrawerData structure to go with it.  This
+ *     structure contains an Intuition NewWindow structure (see the
+ *     "Intuition Windows" chapter for more information):
+ *
+ *         struct DrawerData {
+ *              struct NewWindow dd_NewWindow; structure to open window
+ *              LONG             dd_CurrentX;  current x coordinate of origin
+ *              LONG             dd_CurrentY;  current y coordinate of origin
+ *         };
+ *
+ *     Workbench uses this to hold the current window position and size of
+ *     the window so it will reopen in the same place.
+ *
+ * do_ToolWindow
+ *
+ *     This field is reserved for future use.
+ *
+ * do_StackSize
+ *
+ *     This is the size of the stack (in bytes) used for running the tool.
+ *     If this is NULL, then Workbench will use a reasonable default stack
+ *     size (currently 4K bytes).
+ *
+ *     When a tool is run via the default tool mechanism (i.e., a project
+ *     was activated, not the tool itself), Workbench uses the stack size
+ *     specified in the project's .info file and the tool's .info file is
+ *     ignored.
+ *
+ *-------------------------------------------------------------------------
+ * This program uses code from "sidplay" and an older "infotoxpm" program
+ * Richard Griswold wrote, both of which are offered under GPL.
  *-------------------------------------------------------------------------
  *
  * This program is free software; you can redistribute it and/or
@@ -72,9 +191,10 @@
 #include <stdio.h>
 
 #include "pm_c_util.h"
-#include "pam.h"
-#include "shhopt.h"
 #include "mallocvar.h"
+#include "nstring.h"
+#include "shhopt.h"
+#include "pam.h"
 
 
 typedef struct CmdlineInfo_ {
@@ -101,7 +221,11 @@ typedef struct IconInfo_ {
 
 typedef struct IconHeader_ { /* 20 bytes */
     /* Text of header for one icon image */
-    unsigned char pad0[4];        /* Padding (always seems to be zero) */
+    unsigned char type[4];
+        /* Reverse engineered.  This always seems to be 0x00000000 in
+           icon headers, but we've seen 0x00000010 in some 51-byte object
+           we don't understand.
+        */
     unsigned char iconWidth[2];   /* Width (usually equal to Gadget width) */
     unsigned char iconHeight[2];
         /* Height (usually equal to Gadget height -1) */
@@ -282,16 +406,28 @@ readIconHeader(FILE *         const ifP,
                  "Read only %u of %u bytes",
                  (unsigned)bytesRead, (unsigned)sizeof(ihead));
 
+    if (!memeq(ihead.type, "\0\0\0\0", 4)) {
+        pm_message("Unrecognized object where icon header expected.  "
+                   "First 4 bytes are 0x%02x%02x%02x%02x.  We expect "
+                   "0x00000000",
+                   ihead.type[0], ihead.type[1], ihead.type[2], ihead.type[3]);
+    }
+
     *widthP  = (ihead.iconWidth[0]  << 8) + ihead.iconWidth[1];
     *heightP = (ihead.iconHeight[0] << 8) + ihead.iconHeight[1];
     *depthP  = (ihead.bpp[0]        << 8) + ihead.bpp[1];
 
-    *bpwidthP = ROUNDUP(*widthP, 16);
+    if (*widthP < 1)
+        pm_error("Invalid width value in icon header: %u", *widthP);
+
+    if (*heightP < 1)
+        pm_error("Invalid height value in icon header: %u", *heightP);
 
-    /* Validate number of bit planes */
     if (*depthP > 2 || *depthP < 1)
         pm_error("We don't know how to interpret file with %u bitplanes.  ",
                  *depthP);
+
+    *bpwidthP = ROUNDUP(*widthP, 16);
 }