home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / common / psp.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-24  |  47.6 KB  |  1,806 lines

  1. /* GIMP plug-in to load and save Paint Shop Pro files (.PSP and .TUB)
  2.  *
  3.  * Copyright (C) 1999 Tor Lillqvist
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  */
  19.  
  20. /*
  21.  *
  22.  * Work in progress! Doesn't handle saving yet.
  23.  *
  24.  * For a copy of the PSP file format documentation, surf to
  25.  * http://www.jasc.com.
  26.  *
  27.  */
  28.  
  29. /* set to the level of debugging output you want, 0 for none */
  30. #define PSP_DEBUG 0
  31.  
  32. /* the max number of layers that this plugin should try to load */
  33. #define MAX_LAYERS 64
  34.  
  35. #define IFDBG(level) if (PSP_DEBUG >= level)
  36.  
  37. #include "config.h"
  38.  
  39. #include <glib.h>        /* We want glib.h first because of some
  40.                  * pretty obscure Win32 compilation issues.
  41.                  */
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <sys/types.h>
  46. #include <sys/stat.h>
  47. #include <zlib.h>
  48.  
  49. #include <gtk/gtk.h>
  50.  
  51. #include <libgimp/gimp.h>
  52. #include <libgimp/gimpui.h>
  53. #include <libgimp/gimpparasiteio.h>
  54.  
  55. #include "libgimp/stdplugins-intl.h"
  56.  
  57.  
  58. /* Note that the upcoming PSP version 6 writes PSP file format version
  59.  * 4.0, but the documentation for that apparently isn't publicly
  60.  * available (yet). The format is luckily designed to be somwehat
  61.  * downward compatible, however. The semantics of many of the
  62.  * additional fields and block types can be relatively easily reverse
  63.  * engineered.
  64.  */
  65.  
  66. /* The following was cut and pasted from the PSP file format
  67.  * documentation version 3.0.(Minor stylistic changes done.)
  68.  *
  69.  *
  70.  * To be on the safe side, here is the whole copyright notice from the
  71.  * specification:
  72.  *
  73.  * The Paint Shop Pro File Format Specification (the Specification) is
  74.  * copyright 1998 by Jasc Software, Inc. Jasc grants you a
  75.  * nonexclusive license to use the Specification for the sole purposes
  76.  * of developing software products(s) incorporating the
  77.  * Specification. You are also granted the right to identify your
  78.  * software product(s) as incorporating the Paint Shop Pro Format
  79.  * (PSP) provided that your software in incorporating the
  80.  * Specification complies with the terms, definitions, constraints and
  81.  * specifications contained in the Specification and subject to the
  82.  * following: DISCLAIMER OF WARRANTIES. THE SPECIFICATION IS PROVIDED
  83.  * AS IS. JASC DISCLAIMS ALL OTHER WARRANTIES, EXPRESS OR IMPLIED,
  84.  * INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
  85.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  86.  * NONINFRINGEMENT.
  87.  *
  88.  * You are solely responsible for the selection, use, efficiency and
  89.  * suitability of the Specification for your software products.  OTHER
  90.  * WARRANTIES EXCLUDED. JASC SHALL NOT BE LIABLE FOR ANY DIRECT,
  91.  * INDIRECT, CONSEQUENTIAL, EXEMPLARY, PUNITIVE OR INCIDENTAL DAMAGES
  92.  * ARISING FROM ANY CAUSE EVEN IF JASC HAS BEEN ADVISED OF THE
  93.  * POSSIBILITY OF SUCH DAMAGES. CERTAIN JURISDICTIONS DO NOT PERMIT
  94.  * THE LIMITATION OR EXCLUSION OF INCIDENTAL DAMAGES, SO THIS
  95.  * LIMITATION MAY NOT APPLY TO YOU.  IN NO EVENT WILL JASC BE LIABLE
  96.  * FOR ANY AMOUNT GREATER THAN WHAT YOU ACTUALLY PAID FOR THE
  97.  * SPECIFICATION. Should any warranties be found to exist, such
  98.  * warranties shall be limited in duration to ninety (90) days
  99.  * following the date you receive the Specification.
  100.  *
  101.  * Indemnification. By your inclusion of the Paint Shop Pro File
  102.  * Format in your software product(s) you agree to indemnify and hold
  103.  * Jasc Software, Inc. harmless from any and all claims of any kind or
  104.  * nature made by any of your customers with respect to your software
  105.  * product(s).
  106.  *
  107.  * Export Laws. You agree that you and your customers will not export
  108.  * your software or Specification except in compliance with the laws
  109.  * and regulations of the United States.
  110.  *
  111.  * US Government Restricted Rights. The Specification and any
  112.  * accompanying materials are provided with Restricted Rights. Use,
  113.  * duplication or disclosure by the Government is subject to
  114.  * restrictions as set forth in subparagraph (c)(1)(ii) of The Rights
  115.  * in Technical Data and Computer Software clause at DFARS
  116.  * 252.227-7013, or subparagraphs (c)(1) and (2) of the Commercial
  117.  * Computer Software - Restricted Rights at 48 CFR 52.227-19, as
  118.  * applicable. Contractor/manufacturer is Jasc Software, Inc., PO Box
  119.  * 44997, Eden Prairie MN 55344.
  120.  *
  121.  * Jasc reserves the right to amend, modify, change, revoke or
  122.  * withdraw the Specification at any time and from time to time. Jasc
  123.  * shall have no obligation to support or maintain the Specification.
  124.  */
  125.  
  126. /* Block identifiers.
  127.  */
  128. typedef enum {
  129.   PSP_IMAGE_BLOCK = 0,        /* General Image Attributes Block (main) */
  130.   PSP_CREATOR_BLOCK,        /* Creator Data Block (main) */
  131.   PSP_COLOR_BLOCK,        /* Color Palette Block (main and sub) */
  132.   PSP_LAYER_START_BLOCK,    /* Layer Bank Block (main) */
  133.   PSP_LAYER_BLOCK,        /* Layer Block (sub) */
  134.   PSP_CHANNEL_BLOCK,        /* Channel Block (sub) */
  135.   PSP_SELECTION_BLOCK,        /* Selection Block (main) */
  136.   PSP_ALPHA_BANK_BLOCK,        /* Alpha Bank Block (main) */
  137.   PSP_ALPHA_CHANNEL_BLOCK,    /* Alpha Channel Block (sub) */
  138.   PSP_THUMBNAIL_BLOCK,        /* Thumbnail Block (main) */
  139.   PSP_EXTENDED_DATA_BLOCK,    /* Extended Data Block (main) */
  140.   PSP_TUBE_BLOCK        /* Picture Tube Data Block (main) */
  141. } PSPBlockID;
  142.  
  143. /* Bitmap type.
  144.  */
  145. typedef enum {
  146.   PSP_DIB_IMAGE = 0,        /* Layer color bitmap */
  147.   PSP_DIB_TRANS_MASK,        /* Layer transparency mask bitmap */
  148.   PSP_DIB_USER_MASK,        /* Layer user mask bitmap */
  149.   PSP_DIB_SELECTION,        /* Selection mask bitmap */
  150.   PSP_DIB_ALPHA_MASK,        /* Alpha channel mask bitmap */
  151.   PSP_DIB_THUMBNAIL        /* Thumbnail bitmap */
  152. } PSPDIBType;
  153.  
  154. /* Channel types.
  155.  */
  156. typedef enum {
  157.   PSP_CHANNEL_COMPOSITE = 0,    /* Channel of single channel bitmap */
  158.   PSP_CHANNEL_RED,        /* Red channel of 24 bit bitmap */
  159.   PSP_CHANNEL_GREEN,        /* Green channel of 24 bit bitmap */
  160.   PSP_CHANNEL_BLUE        /* Blue channel of 24 bit bitmap */
  161. } PSPChannelType;
  162.  
  163. /* Possible metrics used to measure resolution.
  164.  */
  165. typedef enum {
  166.   PSP_METRIC_UNDEFINED = 0,    /* Metric unknown */
  167.   PSP_METRIC_INCH,        /* Resolution is in inches */
  168.   PSP_METRIC_CM            /* Resolution is in centimeters */
  169. } PSP_METRIC;
  170.  
  171.  
  172. /* Possible types of compression.
  173.  */
  174. typedef enum {
  175.   PSP_COMP_NONE = 0,        /* No compression */
  176.   PSP_COMP_RLE,            /* RLE compression */
  177.   PSP_COMP_LZ77            /* LZ77 compression */
  178. } PSPCompression;
  179.  
  180. /* Picture tube placement mode.
  181.  */
  182. typedef enum {
  183.   tpmRandom,            /* Place tube images in random intervals */
  184.   tpmConstant            /* Place tube images in constant intervals */
  185. } TubePlacementMode;
  186.  
  187. /* Picture tube selection mode.
  188.  */
  189. typedef enum {
  190.   tsmRandom,            /* Randomly select the next image in  */
  191.                 /* tube to display */
  192.   tsmIncremental,        /* Select each tube image in turn */
  193.   tsmAngular,            /* Select image based on cursor direction */
  194.   tsmPressure,            /* Select image based on pressure  */
  195.                 /* (from pressure-sensitive pad) */
  196.   tsmVelocity            /* Select image based on cursor speed */
  197. } TubeSelectionMode;
  198.  
  199. /* Extended data field types.
  200.  */
  201. typedef enum {
  202.   PSP_XDATA_TRNS_INDEX = 0    /* Transparency index field */
  203. } PSPExtendedDataID;
  204.  
  205. /* Creator field types.
  206.  */
  207. typedef enum {
  208.   PSP_CRTR_FLD_TITLE = 0,    /* Image document title field */
  209.   PSP_CRTR_FLD_CRT_DATE,    /* Creation date field */
  210.   PSP_CRTR_FLD_MOD_DATE,    /* Modification date field */
  211.   PSP_CRTR_FLD_ARTIST,        /* Artist name field */
  212.   PSP_CRTR_FLD_CPYRGHT,        /* Copyright holder name field */
  213.   PSP_CRTR_FLD_DESC,        /* Image document description field */
  214.   PSP_CRTR_FLD_APP_ID,        /* Creating app id field */
  215.   PSP_CRTR_FLD_APP_VER        /* Creating app version field */
  216. } PSPCreatorFieldID;
  217.  
  218. /* Creator application identifiers.
  219.  */
  220. typedef enum {
  221.   PSP_CREATOR_APP_UNKNOWN = 0,    /* Creator application unknown */
  222.   PSP_CREATOR_APP_PAINT_SHOP_PRO /* Creator is Paint Shop Pro */
  223. } PSPCreatorAppID;
  224.  
  225. /* Layer types.
  226.  */
  227. typedef enum {
  228.   PSP_LAYER_NORMAL = 0,        /* Normal layer */
  229.   PSP_LAYER_FLOATING_SELECTION    /* Floating selection layer */
  230. } PSPLayerType;
  231.  
  232. /* Truth values.
  233.  */
  234. #if 0                /* FALSE and TRUE taken by GLib */
  235. typedef enum {
  236.   FALSE = 0,
  237.   TRUE
  238. } PSP_BOOLEAN;
  239. #else
  240. typedef gboolean PSP_BOOLEAN;
  241. #endif
  242.  
  243. /* End of cut&paste from psp spec */
  244.  
  245. /* The following have been reverse engineered.
  246.  * If a new version of the spec becomes available,
  247.  * change to use the type and constant names from it.
  248.  */
  249. typedef enum {
  250.   PSP_BLEND_NORMAL = 0,
  251.   PSP_BLEND_DARKEN,
  252.   PSP_BLEND_LIGHTEN,
  253.   PSP_BLEND_HUE,
  254.   PSP_BLEND_SATURATION,
  255.   PSP_BLEND_COLOR,
  256.   PSP_BLEND_LUMINANCE,
  257.   PSP_BLEND_MULTIPLY,
  258.   PSP_BLEND_SCREEN,
  259.   PSP_BLEND_DISSOLVE,
  260.   PSP_BLEND_OVERLAY,
  261.   PSP_BLEND_HARD_LIGHT,
  262.   PSP_BLEND_SOFT_LIGHT,
  263.   PSP_BLEND_DIFFERENCE,
  264.   PSP_BLEND_DODGE,
  265.   PSP_BLEND_BURN,
  266.   PSP_BLEND_EXCLUSION
  267. } PSPLayerBlendModes;
  268.  
  269. /* End of reverse engineered types */
  270.  
  271. /* We store the various PSP data in own structures.
  272.  * We cannot use structs intended to be direct copies of the file block
  273.  * headers because of struct alignment issues.
  274.  */
  275. typedef struct
  276. {
  277.   guint32 width, height;
  278.   gdouble resolution;
  279.   guchar metric;
  280.   guint16 compression;
  281.   guint16 depth;
  282.   guchar greyscale;
  283.   guint32 active_layer;
  284.   guint16 layer_count;
  285. } PSPimage;
  286.  
  287. /* Declare some local functions.
  288.  */
  289. static void   query      (void);
  290. static void   run        (gchar   *name,
  291.                           gint     nparams,
  292.                           GimpParam  *param,
  293.                           gint    *nreturn_vals,
  294.                           GimpParam **return_vals);
  295. static gint32 load_image (gchar  *filename);
  296. static gint   save_image (gchar  *filename,
  297.               gint32  image_ID,
  298.               gint32  drawable_ID);
  299.  
  300. /* Various local variables...
  301.  */
  302. GimpPlugInInfo PLUG_IN_INFO =
  303. {
  304.   NULL,  /* init_proc  */
  305.   NULL,  /* quit_proc  */
  306.   query, /* query_proc */
  307.   run,   /* run_proc   */
  308. };
  309.  
  310. /* Save info  */
  311. typedef struct
  312. {
  313.   PSPCompression compression;
  314. } PSPSaveVals;
  315.  
  316. typedef struct
  317. {
  318.   gint  run;
  319. } PSPSaveInterface;
  320.  
  321. static PSPSaveVals psvals =
  322. {
  323.   PSP_COMP_LZ77
  324. };
  325.  
  326. static PSPSaveInterface psint =
  327. {
  328.   FALSE   /* run */
  329. };
  330.  
  331. static guint16 major, minor;
  332. static guint tile_height;
  333.  
  334. MAIN ()
  335.  
  336. static void
  337. query (void)
  338. {
  339.   static GimpParamDef load_args[] =
  340.   {
  341.     { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
  342.     { GIMP_PDB_STRING, "filename", "The name of the file to load" },
  343.     { GIMP_PDB_STRING, "raw_filename", "The name of the file to load" }
  344.   };
  345.   static GimpParamDef load_return_vals[] =
  346.   {
  347.     { GIMP_PDB_IMAGE, "image", "Output image" }
  348.   };
  349.   static gint nload_args = sizeof (load_args) / sizeof (load_args[0]);
  350.   static gint nload_return_vals = (sizeof (load_return_vals) /
  351.                    sizeof (load_return_vals[0]));
  352.  
  353. /*    static GimpParamDef save_args[] = */
  354. /*    { */
  355. /*      { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" }, */
  356. /*      { GIMP_PDB_IMAGE, "image", "Input image" }, */
  357. /*      { GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" }, */
  358. /*      { GIMP_PDB_STRING, "filename", "The name of the file to save the image in" }, */
  359. /*      { GIMP_PDB_STRING, "raw_filename", "The name of the file to save the image in" }, */
  360. /*      { GIMP_PDB_INT32, "compression", "Specify 0 for no compression, " */
  361. /*        "1 for RLE, and 2 for LZ77" } */
  362. /*    }; */
  363. /*    static gint nsave_args = sizeof (save_args) / sizeof (save_args[0]); */
  364.  
  365.   gimp_install_procedure ("file_psp_load",
  366.                           "loads images from the Paint Shop Pro PSP file format",
  367.                           "This plug-in loads and saves images in "
  368.               "Paint Shop Pro's native PSP format. "
  369.               "Vector layers aren't handled. Saving isn't "
  370.               "yet implemented.",
  371.               "Tor Lillqvist",
  372.                           "Tor Lillqvist",
  373.                           "1999",
  374.                           "<Load>/PSP",
  375.               NULL,
  376.                           GIMP_PLUGIN,
  377.                           nload_args, nload_return_vals,
  378.                           load_args, load_return_vals);
  379.  
  380. /* Removed until Saving is implemented -- njl195@zepler.org
  381.   gimp_install_procedure ("file_psp_save",
  382.                           "saves images in the Paint Shop Pro PSP file format",
  383.                           "This plug-in loads and saves images in "
  384.               "Paint Shop Pro's native PSP format. "
  385.               "Vector layers aren't handled. Saving isn't "
  386.               "yet implemented.",
  387.                           "Tor Lillqvist",
  388.                           "Tor Lillqvist",
  389.                           "1999",
  390.                           "<Save>/PSP",
  391.               "RGB*, GRAY*, INDEXED*",
  392.                           GIMP_PLUGIN,
  393.                           nsave_args, 0,
  394.                           save_args, NULL);
  395. */
  396.  
  397.   gimp_register_magic_load_handler ("file_psp_load",
  398.                     "psp,tub",
  399.                     "",
  400.                     "0,string,Paint\\040Shop\\040Pro\\040Image\\040File\n\032");
  401. /* Removed until Saving is implemented -- njl195@zepler.org
  402.   gimp_register_save_handler       ("file_psp_save",
  403.                                     "psp,tub",
  404.                                     "");
  405. */
  406. }
  407.  
  408. static void
  409. save_ok_callback (GtkWidget *widget,
  410.           gpointer   data)
  411. {
  412.   psint.run = TRUE;
  413.  
  414.   gtk_widget_destroy (GTK_WIDGET (data));
  415. }
  416.  
  417. static gint
  418. save_dialog (void)
  419. {
  420.   GtkWidget *dlg;
  421.   GtkWidget *frame;
  422.  
  423.   dlg = gimp_dialog_new (_("Save as PSP"), "psp",
  424.              gimp_standard_help_func, "filters/psp.html",
  425.              GTK_WIN_POS_MOUSE,
  426.              FALSE, TRUE, FALSE,
  427.  
  428.              _("OK"), save_ok_callback,
  429.              NULL, NULL, NULL, TRUE, FALSE,
  430.              _("Cancel"), gtk_widget_destroy,
  431.              NULL, 1, NULL, FALSE, TRUE,
  432.  
  433.              NULL);
  434.  
  435.   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
  436.               GTK_SIGNAL_FUNC (gtk_main_quit),
  437.               NULL);
  438.  
  439.   /*  file save type  */
  440.   frame = gimp_radio_group_new2 (TRUE, _("Data Compression"),
  441.                  gimp_radio_button_update,
  442.                  &psvals.compression,
  443.                  (gpointer) psvals.compression,
  444.  
  445.                  _("None"), (gpointer) PSP_COMP_NONE, NULL,
  446.                  _("RLE"),  (gpointer) PSP_COMP_RLE, NULL,
  447.                  _("LZ77"), (gpointer) PSP_COMP_LZ77, NULL,
  448.  
  449.                  NULL);
  450.   gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
  451.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, FALSE, TRUE, 0);
  452.   gtk_widget_show (frame);
  453.  
  454.   gtk_widget_show (dlg);
  455.  
  456.   gtk_main ();
  457.   gdk_flush ();
  458.  
  459.   return psint.run;
  460. }
  461.  
  462. static gchar *
  463. block_name (gint id)
  464. {
  465.   static gchar *block_names[] =
  466.   {
  467.     "IMAGE",
  468.     "CREATOR",
  469.     "COLOR",
  470.     "LAYER_START",
  471.     "LAYER",
  472.     "CHANNEL",
  473.     "SELECTION",
  474.     "ALPHA_BANK",
  475.     "ALPHA_CHANNEL",
  476.     "THUMBNAIL",
  477.     "EXTENDED_DATA",
  478.     "TUBE"
  479.   };
  480.   static gchar *err_name = NULL;
  481.  
  482.   if (id >= 0 && id <= PSP_TUBE_BLOCK)
  483.     return block_names[id];
  484.  
  485.   g_free (err_name);
  486.   err_name = g_strdup_printf ("id=%d", id);
  487.  
  488.   return err_name;
  489. }
  490.  
  491. static gint
  492. read_block_header (FILE    *f,
  493.            guint32 *init_len,
  494.            guint32 *total_len)
  495. {
  496.   guchar buf[4];
  497.   guint16 id;
  498.   long header_start;
  499.   guint32 len;
  500.  
  501.   IFDBG(3) header_start = ftell (f);
  502.  
  503.   if (fread (buf, 4, 1, f) < 1
  504.       || fread (&id, 2, 1, f) < 1
  505.       || fread (&len, 4, 1, f) < 1
  506.       || (major < 4 && fread (total_len, 4, 1, f) < 1))
  507.     {
  508.       g_message ("PSP: Error reading block header");
  509.       fclose (f);
  510.       return -1;
  511.     }
  512.   if (memcmp (buf, "~BK\0", 4) != 0)
  513.     {
  514.       IFDBG(3) 
  515.     g_message ("PSP: Invalid block header at %ld", header_start);
  516.       else
  517.     g_message ("PSP: Invalid block header");
  518.     
  519.       fclose (f);
  520.       return -1;
  521.     }
  522.  
  523.   IFDBG(3) g_message ("PSP: %s at %ld", block_name (id), header_start);
  524.  
  525.   if (major < 4)
  526.     {
  527.       *init_len = GUINT32_FROM_LE (len);
  528.       *total_len = GUINT32_FROM_LE (*total_len);
  529.     }
  530.   else
  531.     {
  532.       /* Version 4.0 seems to have dropped the initial data chunk length
  533.        * field.
  534.        */
  535.       *init_len = 0xDEADBEEF;    /* Intentionally bogus, should not be used */
  536.       *total_len = GUINT32_FROM_LE (len);
  537.     }
  538.  
  539.   return GUINT16_FROM_LE (id);
  540. }
  541.  
  542. static gint
  543. read_general_image_attribute_block (FILE     *f,
  544.                     guint     init_len,
  545.                     guint     total_len,
  546.                     PSPimage *ia)
  547. {
  548.   gchar buf[6];
  549. #ifdef G_HAVE_GINT64
  550.   gint64 res[1];
  551. #else
  552.   guchar res[8];
  553. #endif
  554.  
  555.   if (init_len < 38 || total_len < 38)
  556.     {
  557.       g_message ("PSP: Invalid general image attribute chunk size");
  558.       fclose (f);
  559.       return -1;
  560.     }
  561.  
  562.   if (major >= 4)
  563.     fseek (f, 4, SEEK_CUR);
  564.   
  565.   if (fread (&ia->width, 4, 1, f) < 1
  566.       || fread (&ia->height, 4, 1, f) < 1
  567.       || fread (res, 8, 1, f) < 1
  568.       || fread (&ia->metric, 1, 1, f) < 1
  569.       || fread (&ia->compression, 2, 1, f) < 1
  570.       || fread (&ia->depth, 2, 1, f) < 1
  571.       || fread (buf, 2+4, 1, f) < 1 /* Skip plane and colour count */
  572.       || fread (&ia->greyscale, 1, 1, f) < 1
  573.       || fread (buf, 4, 1, f) < 1 /* Skip total image size */
  574.       || fread (&ia->active_layer, 4, 1, f) < 1
  575.       || fread (&ia->layer_count, 2, 1, f) < 1)
  576.     {
  577.       g_message ("PSP: Error reading general image attribute block");
  578.       fclose (f);
  579.       return -1;
  580.     }
  581.   ia->width = GUINT32_FROM_LE (ia->width);
  582.   ia->height = GUINT32_FROM_LE (ia->height);
  583.  
  584. #ifdef G_HAVE_GINT64
  585.   res[0] = GUINT64_FROM_LE (res[0]);
  586. #else
  587. #if G_BYTE_ORDER == G_BIG_ENDIAN
  588.   {
  589.     /* Swap bytes in the double */
  590.     guchar t;
  591.     t = res[0];
  592.     res[0] = res[7];
  593.     res[7] = t;
  594.     t = res[1];
  595.     res[1] = res[6];
  596.     res[6] = t;
  597.     t = res[2];
  598.     res[2] = res[5];
  599.     res[5] = t;
  600.     t = res[3];
  601.     res[3] = res[4];
  602.     res[4] = t;
  603.   }
  604. #endif
  605. #endif
  606.   memcpy (&ia->resolution, res, 8);
  607.   if (ia->metric == PSP_METRIC_CM)
  608.     ia->resolution /= 2.54;
  609.  
  610.   ia->compression = GUINT16_FROM_LE (ia->compression);
  611.   if (ia->compression > PSP_COMP_LZ77)
  612.     {
  613.       g_message ("PSP: Unknown compression type %d", ia->compression);
  614.       fclose (f);
  615.       return -1;
  616.     }
  617.  
  618.   ia->depth = GUINT16_FROM_LE (ia->depth);
  619.   if (ia->depth != 24)
  620.     {
  621.       g_message ("PSP: Unsupported bit depth %d", ia->depth);
  622.       fclose (f);
  623.       return -1;
  624.     }
  625.  
  626.   ia->active_layer = GUINT32_FROM_LE (ia->active_layer);
  627.   ia->layer_count = GUINT16_FROM_LE (ia->layer_count);
  628.  
  629.   return 0;
  630. }
  631.  
  632. static gint
  633. try_fseek (FILE  *f,
  634.        glong  pos,
  635.        gint   whence)
  636. {
  637.   if (fseek (f, pos, whence) < 0)
  638.     {
  639.       g_message ("PSP: Seek error");
  640.       fclose (f);
  641.       return -1;
  642.     }
  643.   return 0;
  644. }
  645.  
  646. static gint
  647. read_creator_block (FILE     *f,
  648.             gint      image_ID,
  649.             guint     total_len,
  650.             PSPimage *ia)
  651. {
  652.   long data_start;
  653.   guchar buf[4];
  654.   guint16 keyword;
  655.   guint32 length;
  656.   gchar *string;
  657.   gchar *title = NULL, *artist = NULL, *copyright = NULL, *description = NULL;
  658.   guint32 dword;
  659.   guint32 cdate = 0, mdate = 0, appid, appver;
  660.   GString *comment;
  661.   GimpParasite *comment_parasite;
  662.  
  663.   data_start = ftell (f);
  664.   comment = g_string_new (NULL);
  665.  
  666.   while (ftell (f) < data_start + total_len)
  667.     {
  668.       if (fread (buf, 4, 1, f) < 1
  669.       || fread (&keyword, 2, 1, f) < 1
  670.       || fread (&length, 4, 1, f) < 1)
  671.     {
  672.       g_message ("PSP: Error reading creator keyword chunk");
  673.       fclose (f);
  674.       gimp_image_delete (image_ID);
  675.       return -1;
  676.     }
  677.       if (memcmp (buf, "~FL\0", 4) != 0)
  678.     {
  679.       g_message ("PSP: Invalid keyword chunk header");
  680.       fclose (f);
  681.       gimp_image_delete (image_ID);
  682.       return -1;
  683.     }
  684.       keyword = GUINT16_FROM_LE (keyword);
  685.       length = GUINT32_FROM_LE (length);
  686.       switch (keyword)
  687.     {
  688.     case PSP_CRTR_FLD_TITLE:
  689.     case PSP_CRTR_FLD_ARTIST:
  690.     case PSP_CRTR_FLD_CPYRGHT:
  691.     case PSP_CRTR_FLD_DESC:
  692.       string = g_malloc (length + 1);
  693.       if (fread (string, length, 1, f) < 1)
  694.         {
  695.           g_message ("PSP: Error reading creator keyword data");
  696.           fclose (f);
  697.           gimp_image_delete (image_ID);
  698.           return -1;
  699.         }
  700.       switch (keyword)
  701.         {
  702.         case PSP_CRTR_FLD_TITLE:
  703.           g_free (title); title = string; break;
  704.         case PSP_CRTR_FLD_ARTIST:
  705.           g_free (artist); artist = string; break;
  706.         case PSP_CRTR_FLD_CPYRGHT:
  707.           g_free (copyright); copyright = string; break;
  708.         case PSP_CRTR_FLD_DESC:
  709.           g_free (description); description = string; break;
  710.         default:
  711.           g_free (string);
  712.         }
  713.       break;
  714.     case PSP_CRTR_FLD_CRT_DATE:
  715.     case PSP_CRTR_FLD_MOD_DATE:
  716.     case PSP_CRTR_FLD_APP_ID:
  717.     case PSP_CRTR_FLD_APP_VER:
  718.       if (fread (&dword, 4, 1, f) < 1)
  719.         {
  720.           g_message ("PSP: Error reading creator keyword data");
  721.           fclose (f);
  722.           gimp_image_delete (image_ID);
  723.           return -1;
  724.         }
  725.       switch (keyword)
  726.         {
  727.         case PSP_CRTR_FLD_CRT_DATE:
  728.           cdate = dword; break;
  729.         case PSP_CRTR_FLD_MOD_DATE:
  730.           mdate = dword; break;
  731.         case PSP_CRTR_FLD_APP_ID:
  732.           appid = dword; break;
  733.         case PSP_CRTR_FLD_APP_VER:
  734.           appver = dword; break;
  735.         }
  736.       break;
  737.     default:
  738.       if (try_fseek (f, length, SEEK_CUR) < 0)
  739.         {
  740.           gimp_image_delete (image_ID);
  741.           return -1;
  742.         }
  743.       break;
  744.     }
  745.     }
  746.  
  747.   if (title)
  748.     {
  749.       g_string_append (comment, title);
  750.       g_free (title);
  751.       g_string_append (comment, "\n");
  752.     }
  753.   if (artist)
  754.     {
  755.       g_string_append (comment, artist);
  756.       g_free (artist);
  757.       g_string_append (comment, "\n");
  758.     }
  759.   if (copyright)
  760.     {
  761.       g_string_append (comment, "Copyright ");
  762.       g_string_append (comment, copyright);
  763.       g_free (copyright);
  764.       g_string_append (comment, "\n");
  765.     }
  766.   if (description)
  767.     {
  768.       g_string_append (comment, description);
  769.       g_free (description);
  770.       g_string_append (comment, "\n");
  771.     }
  772.   if (comment->len > 0)
  773.     {
  774.       comment_parasite = gimp_parasite_new ("gimp-comment",
  775.                         GIMP_PARASITE_PERSISTENT,
  776.                         strlen (comment->str) + 1,
  777.                         comment->str);
  778.       gimp_image_parasite_attach(image_ID, comment_parasite);
  779.       gimp_parasite_free (comment_parasite);
  780.     }
  781.  
  782.   g_string_free (comment, FALSE);
  783.  
  784.   return 0;
  785. }
  786.  
  787. static void inline
  788. swab_rect (guint32 *rect)
  789. {
  790.   rect[0] = GUINT32_FROM_LE (rect[0]);
  791.   rect[1] = GUINT32_FROM_LE (rect[1]);
  792.   rect[2] = GUINT32_FROM_LE (rect[2]);
  793.   rect[3] = GUINT32_FROM_LE (rect[3]);
  794. }
  795.  
  796. static GimpLayerModeEffects
  797. gimp_layer_mode_from_psp_blend_mode (PSPLayerBlendModes mode)
  798. {
  799.   switch (mode)
  800.     {
  801.     case PSP_BLEND_NORMAL:
  802.       return GIMP_NORMAL_MODE;
  803.     case PSP_BLEND_DARKEN:
  804.       return GIMP_DARKEN_ONLY_MODE;
  805.     case PSP_BLEND_LIGHTEN:
  806.       return GIMP_LIGHTEN_ONLY_MODE;
  807.     case PSP_BLEND_HUE:
  808.       return GIMP_HUE_MODE;
  809.     case PSP_BLEND_SATURATION:
  810.       return GIMP_SATURATION_MODE;
  811.     case PSP_BLEND_COLOR:
  812.       return GIMP_COLOR_MODE;
  813.     case PSP_BLEND_LUMINANCE:
  814.       return GIMP_VALUE_MODE;    /* ??? */
  815.     case PSP_BLEND_MULTIPLY:
  816.       return GIMP_MULTIPLY_MODE;
  817.     case PSP_BLEND_SCREEN:
  818.       return GIMP_SCREEN_MODE;
  819.     case PSP_BLEND_DISSOLVE:
  820.       return GIMP_DISSOLVE_MODE;
  821.     case PSP_BLEND_OVERLAY:
  822.       return GIMP_OVERLAY_MODE;
  823.     case PSP_BLEND_HARD_LIGHT:
  824.     case PSP_BLEND_SOFT_LIGHT:
  825.       return -1;
  826.     case PSP_BLEND_DIFFERENCE:
  827.       return GIMP_DIFFERENCE_MODE;
  828.     case PSP_BLEND_DODGE:
  829.     case PSP_BLEND_BURN:
  830.     case PSP_BLEND_EXCLUSION:
  831.       return -1;        /* ??? */
  832.     }
  833.   return -1;
  834. }
  835.  
  836. static gchar *
  837. blend_mode_name (PSPLayerBlendModes mode)
  838. {
  839.   static gchar *blend_mode_names[] =
  840.   {
  841.     "NORMAL",
  842.     "DARKEN",
  843.     "LIGHTEN",
  844.     "HUE",
  845.     "SATURATION",
  846.     "COLOR",
  847.     "LUMINANCE",
  848.     "MULTIPLY",
  849.     "SCREEN",
  850.     "DISSOLVE",
  851.     "OVERLAY",
  852.     "HARD_LIGHT",
  853.     "SOFT_LIGHT",
  854.     "DIFFERENCE",
  855.     "DODGE",
  856.     "BURN",
  857.     "EXCLUSION"
  858.   };
  859.   static gchar *err_name = NULL;
  860.  
  861.   if (mode >= 0 && mode <= PSP_BLEND_EXCLUSION)
  862.     return blend_mode_names[mode];
  863.  
  864.   g_free (err_name);
  865.   err_name = g_strdup_printf ("unknown layer blend mode %d", mode);
  866.  
  867.   return err_name;
  868. }
  869.  
  870. static gchar *
  871. bitmap_type_name (gint type)
  872. {
  873.   static gchar *bitmap_type_names[] =
  874.   {
  875.     "IMAGE",
  876.     "TRANS_MASK",
  877.     "USER_MASK",
  878.     "SELECTION",
  879.     "ALPHA_MASK",
  880.     "THUMBNAIL"
  881.   };
  882.   static gchar *err_name = NULL;
  883.  
  884.   if (type >= 0 && type <= PSP_DIB_THUMBNAIL)
  885.     return bitmap_type_names[type];
  886.  
  887.   g_free (err_name);
  888.   err_name = g_strdup_printf ("unknown bitmap type %d", type);
  889.  
  890.   return err_name;
  891. }
  892.  
  893. static gchar *
  894. channel_type_name (gint type)
  895. {
  896.   static char *channel_type_names[] =
  897.   {
  898.     "COMPOSITE",
  899.     "RED",
  900.     "GREEN",
  901.     "BLUE"
  902.   };
  903.   static gchar *err_name = NULL;
  904.  
  905.   if (type >= 0 && type <= PSP_DIB_THUMBNAIL)
  906.     return channel_type_names[type];
  907.  
  908.   g_free (err_name);
  909.   err_name = g_strdup_printf ("unknown channel type %d", type);
  910.  
  911.   return err_name;
  912. }
  913.  
  914. static void *
  915. psp_zalloc (void  *opaque,
  916.         guint  items,
  917.         guint  size)
  918. {
  919.   return g_malloc (items*size);
  920. }
  921.  
  922. static void
  923. psp_zfree (void *opaque,
  924.        void *ptr)
  925. {
  926.   g_free (ptr);
  927. }
  928.  
  929. static int
  930. read_channel_data (FILE       *f,
  931.            PSPimage   *ia,
  932.            guchar    **pixels,
  933.            guint       bytespp,
  934.            guint       offset,
  935.            GimpDrawable  *drawable,
  936.            guint32     compressed_len)
  937. {
  938.   gint i, y, width = drawable->width, height = drawable->height;
  939.   gint npixels = width * height;
  940.   guchar *buf, *p, *q, *endq;
  941.   guchar *buf2 = NULL;  /* please the compiler */
  942.   guchar runcount, byte;
  943.   z_stream zstream;
  944.  
  945.   switch (ia->compression)
  946.     {
  947.     case PSP_COMP_NONE:
  948.       if (bytespp == 1)
  949.     {
  950.       if ((width % 4) == 0)
  951.         fread (pixels[0], height * width, 1, f);
  952.       else
  953.         {
  954.           for (y = 0; y < height; y++)
  955.         {
  956.           fread (pixels[y], width, 1, f);
  957.           fseek (f, 4 - (width % 4), SEEK_CUR);
  958.         }
  959.         }
  960.     }
  961.       else
  962.     {
  963.       buf = g_malloc (width);
  964.       for (y = 0; y < height; y++)
  965.         {
  966.           fread (buf, width, 1, f);
  967.           if (width % 4)
  968.         fseek (f, 4 - (width % 4), SEEK_CUR);
  969.           p = buf;
  970.           q = pixels[y] + offset;
  971.           for (i = 0; i < width; i++)
  972.         {
  973.           *q = *p++;
  974.           q += bytespp;
  975.         }
  976.         }
  977.       g_free (buf);
  978.     }
  979.       break;
  980.  
  981.     case PSP_COMP_RLE:
  982.       q = pixels[0] + offset;
  983.       endq = q + npixels * bytespp;
  984.       buf = g_malloc (127);
  985.       while (q < endq)
  986.     {
  987.       p = buf;
  988.       fread (&runcount, 1, 1, f);
  989.       if (runcount > 128)
  990.         {
  991.           runcount -= 128;
  992.           fread (&byte, 1, 1, f);
  993.           memset (buf, byte, runcount);
  994.         }
  995.       else
  996.         fread (buf, runcount, 1, f);
  997.       if (bytespp == 1)
  998.         {
  999.           memmove (q, buf, runcount);
  1000.           q += runcount;
  1001.         }
  1002.       else
  1003.         {
  1004.           p = buf;
  1005.           for (i = 0; i < runcount; i++)
  1006.         {
  1007.           *q = *p++;
  1008.           q += bytespp;
  1009.         }
  1010.         }
  1011.     }
  1012.       g_free (buf);
  1013.       break;
  1014.  
  1015.     case PSP_COMP_LZ77:
  1016.       buf = g_malloc (compressed_len);
  1017.       fread (buf, compressed_len, 1, f);
  1018.       zstream.next_in = buf;
  1019.       zstream.avail_in = compressed_len;
  1020.       zstream.zalloc = psp_zalloc;
  1021.       zstream.zfree = psp_zfree;
  1022.       zstream.opaque = f;
  1023.       if (inflateInit (&zstream) != Z_OK)
  1024.     {
  1025.       g_message ("PSP: zlib error");
  1026.       fclose (f);
  1027.       return -1;
  1028.     }
  1029.       if (bytespp == 1)
  1030.     zstream.next_out = pixels[0];
  1031.       else
  1032.     {
  1033.       buf2 = g_malloc (npixels);
  1034.       zstream.next_out = buf2;
  1035.     }
  1036.       zstream.avail_out = npixels;
  1037.       if (inflate (&zstream, Z_FINISH) != Z_STREAM_END)
  1038.     {
  1039.       g_message ("PSP: zlib error");
  1040.       inflateEnd (&zstream);
  1041.       fclose (f);
  1042.       return -1;
  1043.     }
  1044.       inflateEnd (&zstream);
  1045.       g_free (buf);
  1046.       
  1047.       if (bytespp > 1)
  1048.     {
  1049.       p = buf2;
  1050.       q = pixels[0] + offset;
  1051.       for (i = 0; i < npixels; i++)
  1052.         {
  1053.           *q = *p++;
  1054.           q += bytespp;
  1055.         }
  1056.       g_free (buf2);
  1057.     }
  1058.       break;
  1059.     }
  1060.  
  1061.   return 0;
  1062. }
  1063.  
  1064. static gint
  1065. read_layer_block (FILE     *f,
  1066.           gint      image_ID,
  1067.           guint     total_len,
  1068.           PSPimage *ia)
  1069. {
  1070.   gint i;
  1071.   long block_start, sub_block_start, channel_start;
  1072.   gint sub_id;
  1073.   guint32 sub_init_len, sub_total_len;
  1074.   guchar *name;
  1075.   guint16 namelen;
  1076.   guchar type, opacity, blend_mode, visibility, transparency_protected;
  1077.   guchar link_group_id, mask_linked, mask_disabled;
  1078.   guint32 image_rect[4], saved_image_rect[4], mask_rect[4], saved_mask_rect[4];
  1079.   gboolean null_layer = FALSE;
  1080.   guint16 bitmap_count, channel_count;
  1081.   GimpImageType drawable_type;
  1082.   guint32 layer_ID = 0;
  1083.   GimpLayerModeEffects layer_mode;
  1084.   guint32 channel_init_len, channel_total_len;
  1085.   guint32 compressed_len, uncompressed_len;
  1086.   guint16 bitmap_type, channel_type;
  1087.   gint width, height, bytespp, offset;
  1088.   guchar **pixels, *pixel;
  1089.   GimpDrawable *drawable;
  1090.   GimpPixelRgn pixel_rgn;
  1091.  
  1092.   block_start = ftell (f);
  1093.  
  1094.   while (ftell (f) < block_start + total_len)
  1095.     {
  1096.       /* Read the layer sub-block header */
  1097.       sub_id = read_block_header (f, &sub_init_len, &sub_total_len);
  1098.       if (sub_id == -1)
  1099.     {
  1100.       gimp_image_delete (image_ID);
  1101.       return -1;
  1102.     }
  1103.       if (sub_id != PSP_LAYER_BLOCK)
  1104.     {
  1105.       g_message ("PSP: Invalid layer sub-block %s, should be LAYER",
  1106.              block_name (sub_id));
  1107.       fclose (f);
  1108.       gimp_image_delete (image_ID);
  1109.       return -1;
  1110.     }
  1111.  
  1112.       sub_block_start = ftell (f);
  1113.  
  1114.       /* Read layer information chunk */
  1115.       if (major >= 4)
  1116.     {
  1117.       if (fseek (f, 4, SEEK_CUR) < 0
  1118.           || fread (&namelen, 2, 1, f) < 1
  1119.           || ((namelen = GUINT16_FROM_LE (namelen)) && FALSE)
  1120.           || (name = g_malloc (namelen + 1)) == NULL
  1121.           || fread (name, namelen, 1, f) < 1
  1122.           || fread (&type, 1, 1, f) < 1
  1123.           || fread (&image_rect, 16, 1, f) < 1
  1124.           || fread (&saved_image_rect, 16, 1, f) < 1
  1125.           || fread (&opacity, 1, 1, f) < 1
  1126.           || fread (&blend_mode, 1, 1, f) < 1
  1127.           || fread (&visibility, 1, 1, f) < 1
  1128.           || fread (&transparency_protected, 1, 1, f) < 1
  1129.           || fread (&link_group_id, 1, 1, f) < 1
  1130.           || fread (&mask_rect, 16, 1, f) < 1
  1131.           || fread (&saved_mask_rect, 16, 1, f) < 1
  1132.           || fread (&mask_linked, 1, 1, f) < 1
  1133.           || fread (&mask_disabled, 1, 1, f) < 1
  1134.           || fseek (f, 47, SEEK_CUR) < 0
  1135.           || fread (&bitmap_count, 2, 1, f) < 1
  1136.           || fread (&channel_count, 2, 1, f) < 1)
  1137.         {
  1138.           g_message ("PSP: Error reading layer information chunk");
  1139.           fclose (f);
  1140.           gimp_image_delete (image_ID);
  1141.           return -1;
  1142.         }
  1143.       name[namelen] = 0;
  1144.       type = PSP_LAYER_NORMAL; /* ??? */
  1145.     }
  1146.       else
  1147.     {
  1148.       name = g_malloc (257);
  1149.       name[256] = 0;
  1150.       if (fread (name, 256, 1, f) < 1
  1151.           || fread (&type, 1, 1, f) < 1
  1152.           || fread (&image_rect, 16, 1, f) < 1
  1153.           || fread (&saved_image_rect, 16, 1, f) < 1
  1154.           || fread (&opacity, 1, 1, f) < 1
  1155.           || fread (&blend_mode, 1, 1, f) < 1
  1156.           || fread (&visibility, 1, 1, f) < 1
  1157.           || fread (&transparency_protected, 1, 1, f) < 1
  1158.           || fread (&link_group_id, 1, 1, f) < 1
  1159.           || fread (&mask_rect, 16, 1, f) < 1
  1160.           || fread (&saved_mask_rect, 16, 1, f) < 1
  1161.           || fread (&mask_linked, 1, 1, f) < 1
  1162.           || fread (&mask_disabled, 1, 1, f) < 1
  1163.           || fseek (f, 43, SEEK_CUR) < 0
  1164.           || fread (&bitmap_count, 2, 1, f) < 1
  1165.           || fread (&channel_count, 2, 1, f) < 1)
  1166.         {
  1167.           g_message ("PSP: Error reading layer information chunk");
  1168.           g_free (name);
  1169.           fclose (f);
  1170.           gimp_image_delete (image_ID);
  1171.           return -1;
  1172.         }
  1173.     }
  1174.  
  1175.       if (type == PSP_LAYER_FLOATING_SELECTION)
  1176.     g_message ("PSP: Floating selection restored as normal layer");
  1177.  
  1178.       swab_rect (image_rect);
  1179.       swab_rect (saved_image_rect);
  1180.       swab_rect (mask_rect);
  1181.       swab_rect (saved_mask_rect);
  1182.       bitmap_count = GUINT16_FROM_LE (bitmap_count);
  1183.       channel_count = GUINT16_FROM_LE (channel_count);
  1184.  
  1185.       layer_mode = gimp_layer_mode_from_psp_blend_mode (blend_mode);
  1186.       if ((int) layer_mode == -1)
  1187.     {
  1188.       g_message ("PSP: Unsupported PSP layer blend mode %s "
  1189.              "for layer %s, setting layer invisible",
  1190.              blend_mode_name (blend_mode), name);
  1191.       layer_mode = GIMP_NORMAL_MODE;
  1192.       visibility = FALSE;
  1193.     }
  1194.  
  1195.       width = saved_image_rect[2] - saved_image_rect[0];
  1196.       height = saved_image_rect[3] - saved_image_rect[1];
  1197.  
  1198.       IFDBG(2) g_message
  1199.     ("PSP: layer: %s %dx%d (%dx%d) @%d,%d opacity %d blend_mode %s "
  1200.      "%d bitmaps %d channels",
  1201.      name,
  1202.      image_rect[2] - image_rect[0], image_rect[3] - image_rect[1],
  1203.      width, height,
  1204.      saved_image_rect[0], saved_image_rect[1],
  1205.      opacity, blend_mode_name (blend_mode),
  1206.      bitmap_count, channel_count);
  1207.  
  1208.       IFDBG(2) g_message
  1209.     ("PSP: mask %dx%d (%dx%d) @%d,%d",
  1210.      mask_rect[2] - mask_rect[0],
  1211.      mask_rect[3] - mask_rect[1],
  1212.      saved_mask_rect[2] - saved_mask_rect[0],
  1213.      saved_mask_rect[3] - saved_mask_rect[1],
  1214.      saved_mask_rect[0], saved_mask_rect[1]);
  1215.  
  1216.       if (width == 0)
  1217.     {
  1218.       width++;
  1219.       null_layer = TRUE;
  1220.     }
  1221.       if (height == 0)
  1222.     {
  1223.       height++;
  1224.       null_layer = TRUE;
  1225.     }
  1226.  
  1227.       if (ia->greyscale)
  1228.     if (!null_layer && bitmap_count == 1)
  1229.       drawable_type = GIMP_GRAY_IMAGE, bytespp = 1;
  1230.     else
  1231.       drawable_type = GIMP_GRAYA_IMAGE, bytespp = 1;
  1232.       else
  1233.     if (!null_layer && bitmap_count == 1)
  1234.       drawable_type = GIMP_RGB_IMAGE, bytespp = 3;
  1235.     else
  1236.       drawable_type = GIMP_RGBA_IMAGE, bytespp = 4;
  1237.  
  1238.       layer_ID = gimp_layer_new (image_ID, name,
  1239.                  width, height,
  1240.                  drawable_type,
  1241.                  100.0 * opacity / 255.0,
  1242.                  layer_mode);
  1243.       if (layer_ID == -1)
  1244.     {
  1245.       g_message ("PSP: Error creating layer");
  1246.       fclose (f);
  1247.       gimp_image_delete (image_ID);
  1248.       return -1;
  1249.     }
  1250.  
  1251.       g_free (name);
  1252.  
  1253.       gimp_image_add_layer (image_ID, layer_ID, -1);
  1254.  
  1255.       if (saved_image_rect[0] != 0 || saved_image_rect[1] != 0)
  1256.     gimp_layer_set_offsets (layer_ID,
  1257.                 saved_image_rect[0], saved_image_rect[1]);
  1258.  
  1259.       if (!visibility)
  1260.     gimp_layer_set_visible (layer_ID, FALSE);
  1261.       
  1262.       gimp_layer_set_preserve_transparency (layer_ID, transparency_protected);
  1263.  
  1264.       if (major < 4)
  1265.     if (try_fseek (f, sub_block_start + sub_init_len, SEEK_SET) < 0)
  1266.       {
  1267.         gimp_image_delete (image_ID);
  1268.         return -1;
  1269.       }
  1270.  
  1271.       pixel = g_malloc0 (height * width * bytespp);
  1272.       if (null_layer)
  1273.     pixels = NULL;
  1274.       else
  1275.     {
  1276.       pixels = g_new(guchar *, height);
  1277.       for (i = 0; i < height; i++)
  1278.         pixels[i] = pixel + width * bytespp * i;
  1279.     }
  1280.  
  1281.       drawable = gimp_drawable_get (layer_ID);
  1282.       gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
  1283.                width, height, TRUE, FALSE);
  1284.  
  1285.       gimp_tile_cache_size (tile_height * width * bytespp);
  1286.  
  1287.       /* Read the layer channel sub-blocks */
  1288.       while (ftell (f) < sub_block_start + sub_total_len)
  1289.     {
  1290.       sub_id = read_block_header (f, &channel_init_len,
  1291.                       &channel_total_len);
  1292.       if (sub_id == -1)
  1293.         {
  1294.           gimp_image_delete (image_ID);
  1295.           return -1;
  1296.         }
  1297.  
  1298.       if (sub_id != PSP_CHANNEL_BLOCK)
  1299.         {
  1300.           g_message ("PSP: Invalid layer sub-block %s, should be CHANNEL",
  1301.              block_name (sub_id));
  1302.           fclose (f);
  1303.           gimp_image_delete (image_ID);
  1304.           return -1;
  1305.         }
  1306.  
  1307.       channel_start = ftell (f);
  1308.  
  1309.       if (major == 4)
  1310.         fseek (f, 4, SEEK_CUR); /* Unknown field */
  1311.       
  1312.       if (fread (&compressed_len, 4, 1, f) < 1
  1313.           || fread (&uncompressed_len, 4, 1, f) < 1
  1314.           || fread (&bitmap_type, 2, 1, f) < 1
  1315.           || fread (&channel_type, 2, 1, f) < 1)
  1316.         {
  1317.           g_message ("PSP: Error reading channel information chunk");
  1318.           fclose (f);
  1319.           gimp_image_delete (image_ID);
  1320.           return -1;
  1321.         }
  1322.  
  1323.       compressed_len = GUINT32_FROM_LE (compressed_len);
  1324.       uncompressed_len = GUINT32_FROM_LE (uncompressed_len);
  1325.       bitmap_type = GUINT16_FROM_LE (bitmap_type);
  1326.       channel_type = GUINT16_FROM_LE (channel_type);
  1327.  
  1328.       if (bitmap_type > PSP_DIB_USER_MASK)
  1329.         {
  1330.           g_message ("PSP: Invalid bitmap type %d "
  1331.              "in channel information chunk",
  1332.              bitmap_type);
  1333.           fclose (f);
  1334.           gimp_image_delete (image_ID);
  1335.           return -1;
  1336.         }
  1337.  
  1338.       if (channel_type > PSP_CHANNEL_BLUE)
  1339.         {
  1340.           g_message ("PSP: Invalid channel type %d "
  1341.              "in channel information chunk",
  1342.              channel_type);
  1343.           fclose (f);
  1344.           gimp_image_delete (image_ID);
  1345.           return -1;
  1346.         }
  1347.  
  1348.       IFDBG(2) g_message ("PSP: channel: %s %s %d (%d) bytes "
  1349.                   "%d bytespp",
  1350.                   bitmap_type_name (bitmap_type),
  1351.                   channel_type_name (channel_type),
  1352.                   uncompressed_len, compressed_len,
  1353.                   bytespp);
  1354.  
  1355.       if (bitmap_type == PSP_DIB_TRANS_MASK)
  1356.         offset = 3;
  1357.       else
  1358.         offset = channel_type - PSP_CHANNEL_RED;
  1359.  
  1360.       if (major < 4)
  1361.         if (try_fseek (f, channel_start + channel_init_len, SEEK_SET) < 0)
  1362.           {
  1363.         gimp_image_delete (image_ID);
  1364.         return -1;
  1365.           }
  1366.       
  1367.       if (!null_layer)
  1368.         if (read_channel_data (f, ia, pixels, bytespp,
  1369.                    offset, drawable, compressed_len) == -1)
  1370.           {
  1371.         gimp_image_delete (image_ID);
  1372.         return -1;
  1373.           }
  1374.  
  1375.       if (try_fseek (f, channel_start + channel_total_len, SEEK_SET) < 0)
  1376.         {
  1377.           gimp_image_delete (image_ID);
  1378.           return -1;
  1379.         }
  1380.     }
  1381.  
  1382.       gimp_pixel_rgn_set_rect (&pixel_rgn, pixel, 0, 0, width, height);
  1383.  
  1384.       gimp_drawable_flush (drawable);
  1385.       gimp_drawable_detach (drawable);
  1386.  
  1387.       g_free (pixels);
  1388.       g_free (pixel);
  1389.     }
  1390.   if (try_fseek (f, block_start + total_len, SEEK_SET) < 0)
  1391.     {
  1392.       gimp_image_delete (image_ID);
  1393.       return -1;
  1394.     }
  1395.  
  1396.   return layer_ID;
  1397. }
  1398.  
  1399. static gint
  1400. read_tube_block (FILE     *f,
  1401.          gint      image_ID,
  1402.          guint     total_len,
  1403.          PSPimage *ia)
  1404. {
  1405.   guint16 version;
  1406.   guchar name[514];
  1407.   guint32 step_size, column_count, row_count, cell_count;
  1408.   guint32 placement_mode, selection_mode;
  1409.   gint i;
  1410.   GimpPixPipeParams params;
  1411.   GimpParasite *pipe_parasite;
  1412.   gchar *parasite_text;
  1413.  
  1414.   gimp_pixpipe_params_init (¶ms);
  1415.  
  1416.   if (fread (&version, 2, 1, f) < 1
  1417.       || fread (name, 513, 1, f) < 1
  1418.       || fread (&step_size, 4, 1, f) < 1
  1419.       || fread (&column_count, 4, 1, f) < 1
  1420.       || fread (&row_count, 4, 1, f) < 1
  1421.       || fread (&cell_count, 4, 1, f) < 1
  1422.       || fread (&placement_mode, 4, 1, f) < 1
  1423.       || fread (&selection_mode, 4, 1, f) < 1)
  1424.     {
  1425.       g_message ("PSP: Error reading tube data chunk");
  1426.       fclose (f);
  1427.       gimp_image_delete (image_ID);
  1428.       return -1;
  1429.     }
  1430.   name[513] = 0;
  1431.   version = GUINT16_FROM_LE (version);
  1432.   params.step = GUINT32_FROM_LE (step_size);
  1433.   params.cols = GUINT32_FROM_LE (column_count);
  1434.   params.rows = GUINT32_FROM_LE (row_count);
  1435.   params.ncells = GUINT32_FROM_LE (cell_count);
  1436.   placement_mode = GUINT32_FROM_LE (placement_mode);
  1437.   selection_mode = GUINT32_FROM_LE (selection_mode);
  1438.  
  1439.   for (i = 1; i < column_count; i++)
  1440.     gimp_image_add_vguide (image_ID, (ia->width * i)/column_count);
  1441.   for (i = 1; i < row_count; i++)
  1442.     gimp_image_add_hguide (image_ID, (ia->height * i)/row_count);
  1443.  
  1444.   /* We use a parasite to pass in the tube (pipe) parameters in
  1445.    * case we will have any use of those, for instance in the gpb
  1446.    * plug-in that saves a GIMP image pipe.
  1447.    */
  1448.   params.dim = 1;
  1449.   params.cellwidth = ia->width / params.cols;
  1450.   params.cellheight = ia->height / params.rows;
  1451.   params.placement = (placement_mode == tpmRandom ? "random" :
  1452.               (placement_mode == tpmConstant ? "constant" :
  1453.                "default"));
  1454.   params.rank[0] = params.ncells;
  1455.   params.selection[0] = (selection_mode == tsmRandom ? "random" :
  1456.              (selection_mode == tsmIncremental ? "incremental" :
  1457.               (selection_mode == tsmAngular ? "angular" :
  1458.                (selection_mode == tsmPressure ? "pressure" :
  1459.                 (selection_mode == tsmVelocity ? "velocity" :
  1460.                  "default")))));
  1461.   parasite_text = gimp_pixpipe_params_build (¶ms);
  1462.  
  1463.   IFDBG(2) g_message ("parasite: %s", parasite_text);
  1464.  
  1465.   pipe_parasite = gimp_parasite_new ("gimp-brush-pipe-parameters",
  1466.                      GIMP_PARASITE_PERSISTENT,
  1467.                      strlen (parasite_text) + 1, parasite_text);
  1468.   gimp_image_parasite_attach (image_ID, pipe_parasite);
  1469.   gimp_parasite_free (pipe_parasite);
  1470.   g_free (parasite_text);
  1471.  
  1472.   return 0;
  1473. }
  1474.  
  1475. static gchar *
  1476. compression_name (gint compression)
  1477. {
  1478.   switch (compression)
  1479.     {
  1480.     case PSP_COMP_NONE:
  1481.       return "no compression";
  1482.     case PSP_COMP_RLE:
  1483.       return "RLE";
  1484.     case PSP_COMP_LZ77:
  1485.       return "LZ77";
  1486.     }
  1487.   g_assert_not_reached ();
  1488.  
  1489.   return NULL;
  1490. }
  1491.  
  1492. static gint32
  1493. load_image (gchar *filename)
  1494. {
  1495.   FILE *f;
  1496.   struct stat st;
  1497.   char buf[32];
  1498.   PSPimage ia;
  1499.   guint32 block_init_len, block_total_len;
  1500.   long block_start;
  1501.   PSPBlockID id = -1;
  1502.   gint block_number;
  1503.  
  1504.   gint32 image_ID = -1;
  1505.  
  1506.   if (stat (filename, &st) == -1)
  1507.     return -1;
  1508.  
  1509.   f = fopen (filename, "rb");
  1510.   if (f == NULL)
  1511.     return -1;
  1512.  
  1513.   /* Read thePSP File Header */
  1514.   if (fread (buf, 32, 1, f) < 1
  1515.       || fread (&major, 2, 1, f) < 1
  1516.       || fread (&minor, 2, 1, f) < 1)
  1517.     {
  1518.       g_message ("PSP: Error reading file header");
  1519.       fclose (f);
  1520.       return -1;
  1521.     }
  1522.   if (memcmp (buf, "Paint Shop Pro Image File\n\032\0\0\0\0\0", 32) != 0)
  1523.     {
  1524.       g_message ("PSP: Incorrect file signature");
  1525.       fclose (f);
  1526.       return -1;
  1527.     }
  1528.  
  1529.   major = GUINT16_FROM_LE (major);
  1530.   minor = GUINT16_FROM_LE (minor);
  1531.   /* I only have the documentation for file format version 3.0,
  1532.    * but PSP 6 writes version 4.0. Let's hope it's backwards compatible.
  1533.    * Earlier versions probably don't have all the fields I expect
  1534.    * so don't accept those.
  1535.    */
  1536.   if (major < 3)
  1537.     {
  1538.       g_message ("PSP: Unsupported PSP file format version "
  1539.          "%d.%d, only knows 3.0 (and later?)",
  1540.          major, minor);
  1541.       fclose (f);
  1542.       return -1;
  1543.     }
  1544.   else if (major == 3)
  1545.     ; /* OK */
  1546.   else if (major == 4 && minor == 0)
  1547.     g_message ("PSP: Warning: PSP file format version "
  1548.            "4.0. Support for this format version "
  1549.            "is based on reverse engineering, "
  1550.            "as no documentation has been made available");
  1551.   else
  1552.     {
  1553.       g_message ("PSP: Unsupported PSP file format version %d.%d",
  1554.          major, minor);
  1555.       fclose (f);
  1556.       return -1;
  1557.     }
  1558.  
  1559.   /* Read all the blocks */
  1560.   block_number = 0;
  1561.  
  1562.   IFDBG(3) g_message ("PSP: size = %d", (int)st.st_size);
  1563.   while (ftell (f) != st.st_size
  1564.      && (id = read_block_header (f, &block_init_len,
  1565.                      &block_total_len)) != -1)
  1566.     {
  1567.       block_start = ftell (f);
  1568.  
  1569.       if (id == PSP_IMAGE_BLOCK)
  1570.     {
  1571.       if (block_number != 0)
  1572.         {
  1573.           g_message ("PSP: Duplicate General Image Attributes block");
  1574.           fclose (f);
  1575.           return -1;
  1576.         }
  1577.       if (read_general_image_attribute_block (f, block_init_len,
  1578.                           block_total_len, &ia) == -1)
  1579.         return -1;
  1580.  
  1581.       IFDBG(2) g_message ("PSP: %d dpi %dx%d %s",
  1582.                   (int) ia.resolution,
  1583.                   ia.width, ia.height,
  1584.                   compression_name (ia.compression));
  1585.  
  1586.       image_ID = gimp_image_new (ia.width, ia.height,
  1587.                      ia.greyscale ? GIMP_GRAY : GIMP_RGB);
  1588.       if (image_ID == -1)
  1589.         return -1;
  1590.  
  1591.       gimp_image_set_filename (image_ID, filename);
  1592.  
  1593.       gimp_image_set_resolution (image_ID, ia.resolution, ia.resolution);
  1594.     }
  1595.       else
  1596.     {
  1597.       if (block_number == 0)
  1598.         {
  1599.           g_message ("PSP: Missing General Image Attributes block");
  1600.           fclose (f);
  1601.           gimp_image_delete (image_ID);
  1602.           return -1;
  1603.         }
  1604.       switch (id)
  1605.         {
  1606.         case PSP_CREATOR_BLOCK:
  1607.           if (read_creator_block (f, image_ID, block_total_len, &ia) == -1)
  1608.         return -1;
  1609.           break;
  1610.  
  1611.         case PSP_COLOR_BLOCK:
  1612.           break;        /* Not yet implemented */
  1613.  
  1614.         case PSP_LAYER_START_BLOCK:
  1615.           if (read_layer_block (f, image_ID, block_total_len, &ia) == -1)
  1616.         return -1;
  1617.           break;
  1618.  
  1619.         case PSP_SELECTION_BLOCK:
  1620.           break;        /* Not yet implemented */
  1621.  
  1622.         case PSP_ALPHA_BANK_BLOCK:
  1623.           break;        /* Not yet implemented */
  1624.  
  1625.         case PSP_THUMBNAIL_BLOCK:
  1626.           break;        /* No use for it */
  1627.  
  1628.         case PSP_EXTENDED_DATA_BLOCK:
  1629.           break;        /* Not yet implemented */
  1630.  
  1631.         case PSP_TUBE_BLOCK:
  1632.           if (read_tube_block (f, image_ID, block_total_len, &ia) == -1)
  1633.         return -1;
  1634.           break;
  1635.  
  1636.         case PSP_LAYER_BLOCK:
  1637.         case PSP_CHANNEL_BLOCK:
  1638.         case PSP_ALPHA_CHANNEL_BLOCK:
  1639.           g_message ("PSP: Sub-block %s should not occur "
  1640.              "at main level of file",
  1641.              block_name (id));
  1642.           break;
  1643.  
  1644.         default:
  1645.           g_message ("PSP: Unrecognized block id %d", id);
  1646.           break;
  1647.         }
  1648.     }
  1649.  
  1650.       if (block_start + block_total_len >= st.st_size)
  1651.     break;
  1652.  
  1653.       if (try_fseek (f, block_start + block_total_len, SEEK_SET) < 0)
  1654.     {
  1655.       gimp_image_delete (image_ID);
  1656.       return -1;
  1657.     }
  1658.       block_number++;
  1659.     }
  1660.  
  1661.   if (id == -1)
  1662.     {
  1663.       fclose (f);
  1664.       gimp_image_delete (image_ID);
  1665.       return -1;
  1666.     }
  1667.  
  1668.   fclose (f);
  1669.  
  1670.   return image_ID;
  1671. }
  1672.  
  1673. static gint
  1674. save_image (gchar  *filename,
  1675.         gint32  image_ID,
  1676.         gint32  drawable_ID)
  1677. {
  1678.   g_message ("PSP: Saving not implemented yet");
  1679.  
  1680.   return FALSE;
  1681. }
  1682.  
  1683. static void
  1684. run (gchar   *name,
  1685.      gint     nparams,
  1686.      GimpParam  *param,
  1687.      gint    *nreturn_vals,
  1688.      GimpParam **return_vals)
  1689. {
  1690.   static GimpParam values[2];
  1691.   GimpRunModeType  run_mode;
  1692.   GimpPDBStatusType   status = GIMP_PDB_SUCCESS;
  1693.   gint32        image_ID;
  1694.   gint32        drawable_ID;
  1695.   GimpExportReturnType export = GIMP_EXPORT_CANCEL;
  1696.  
  1697.   tile_height = gimp_tile_height ();
  1698.  
  1699.   run_mode = param[0].data.d_int32;
  1700.  
  1701.   *nreturn_vals = 1;
  1702.   *return_vals  = values;
  1703.   values[0].type          = GIMP_PDB_STATUS;
  1704.   values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
  1705.  
  1706.   if (strcmp (name, "file_psp_load") == 0)
  1707.     {
  1708.       image_ID = load_image (param[1].data.d_string);
  1709.  
  1710.       if (image_ID != -1)
  1711.     {
  1712.       *nreturn_vals = 2;
  1713.       values[1].type         = GIMP_PDB_IMAGE;
  1714.       values[1].data.d_image = image_ID;
  1715.     }
  1716.       else
  1717.     {
  1718.       status = GIMP_PDB_EXECUTION_ERROR;
  1719.     }
  1720.     }
  1721.   else if (strcmp (name, "file_psp_save") == 0)
  1722.     {
  1723.       image_ID = param[1].data.d_int32;
  1724.       drawable_ID = param[2].data.d_int32;
  1725.  
  1726.       /*  eventually export the image */ 
  1727.       switch (run_mode)
  1728.     {
  1729.     case GIMP_RUN_INTERACTIVE:
  1730.     case GIMP_RUN_WITH_LAST_VALS:
  1731.       INIT_I18N_UI();
  1732.       gimp_ui_init ("psp", FALSE);
  1733.       export = gimp_export_image (&image_ID, &drawable_ID, "PSP", 
  1734.                       (GIMP_EXPORT_CAN_HANDLE_RGB |
  1735.                        GIMP_EXPORT_CAN_HANDLE_GRAY |
  1736.                        GIMP_EXPORT_CAN_HANDLE_INDEXED |
  1737.                        GIMP_EXPORT_CAN_HANDLE_ALPHA  |
  1738.                        GIMP_EXPORT_CAN_HANDLE_LAYERS));
  1739.       if (export == GIMP_EXPORT_CANCEL)
  1740.         {
  1741.           values[0].data.d_status = GIMP_PDB_CANCEL;
  1742.           return;
  1743.         }
  1744.       break;
  1745.     default:
  1746.       break;
  1747.     }
  1748.  
  1749.       switch (run_mode)
  1750.     {
  1751.     case GIMP_RUN_INTERACTIVE:
  1752.       
  1753.       /*  Possibly retrieve data  */
  1754.       gimp_get_data ("file_pnm_save", &psvals);
  1755.  
  1756.       /*  First acquire information with a dialog  */
  1757.       if (! save_dialog ())
  1758.         status = GIMP_PDB_CANCEL;
  1759.       break;
  1760.  
  1761.     case GIMP_RUN_NONINTERACTIVE:
  1762.       /*  Make sure all the arguments are there!  */
  1763.       if (nparams != 6)
  1764.         {
  1765.           status = GIMP_PDB_CALLING_ERROR;
  1766.         }
  1767.       else
  1768.         {
  1769.           psvals.compression = (param[5].data.d_int32) ? TRUE : FALSE;
  1770.  
  1771.           if (param[5].data.d_int32 < 0 ||
  1772.           param[5].data.d_int32 > PSP_COMP_LZ77)
  1773.         status = GIMP_PDB_CALLING_ERROR;
  1774.         }
  1775.  
  1776.     case GIMP_RUN_WITH_LAST_VALS:
  1777.       gimp_get_data ("file_psp_save", &psvals);
  1778.       break;
  1779.  
  1780.     default:
  1781.       break;
  1782.     }
  1783.  
  1784.       if (status == GIMP_PDB_SUCCESS)
  1785.     {
  1786.       if (save_image (param[3].data.d_string, image_ID, drawable_ID))
  1787.         {
  1788.           gimp_set_data ("file_psp_save", &psvals, sizeof (PSPSaveVals));
  1789.         }
  1790.       else
  1791.         {
  1792.           status = GIMP_PDB_EXECUTION_ERROR;
  1793.         }
  1794.     }
  1795.  
  1796.       if (export == GIMP_EXPORT_EXPORT)
  1797.     gimp_image_delete (image_ID);
  1798.     }
  1799.   else
  1800.     {
  1801.       status = GIMP_PDB_CALLING_ERROR;
  1802.     }
  1803.  
  1804.   values[0].data.d_status = status;
  1805. }
  1806.