summaryrefslogtreecommitdiffstats
path: root/kernel/kls_psp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kls_psp')
-rw-r--r--kernel/kls_psp/Makefile.am9
-rw-r--r--kernel/kls_psp/fmt_codec_psp.cpp635
-rw-r--r--kernel/kls_psp/fmt_codec_psp_defs.h249
3 files changed, 893 insertions, 0 deletions
diff --git a/kernel/kls_psp/Makefile.am b/kernel/kls_psp/Makefile.am
new file mode 100644
index 0000000..d9ae202
--- /dev/null
+++ b/kernel/kls_psp/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I../include
+
+pkglib_LTLIBRARIES = libkls_psp.la
+
+libkls_psp_la_SOURCES = fmt_codec_psp.cpp fmt_codec_psp_defs.h
+
+libkls_psp_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_psp_la_LIBADD = ${SQ_LOCAL_RPATH}
diff --git a/kernel/kls_psp/fmt_codec_psp.cpp b/kernel/kls_psp/fmt_codec_psp.cpp
new file mode 100644
index 0000000..e77caa4
--- /dev/null
+++ b/kernel/kls_psp/fmt_codec_psp.cpp
@@ -0,0 +1,635 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <cstdlib>
+#include <stdio.h>
+#include <string.h>
+#include <algorithm>
+#include <stdlib.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_psp_defs.h"
+#include "fmt_codec_psp.h"
+
+#include "ksquirrel-libs/error.h"
+
+#include "../xpm/codec_psp.xpm"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.0";
+ o->name = "PaintShop Pro";
+ o->filter = "*.psp ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-psp";
+ o->pixmap = codec_psp;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = false;
+}
+
+/************** Utility functions from DevIL *********************/
+
+//-----------------------------------------------------------------------------
+//
+// ImageLib Sources
+// Copyright (C) 2000-2002 by Denton Woods
+// Last modified: 05/04/2002 <--Y2K Compliant! =]
+//
+// Filename: src-IL/src/il_psp.c
+//
+// Description: Reads a Paint Shop Pro file.
+//
+//-----------------------------------------------------------------------------
+
+
+bool fmt_codec::iGetPspHead()
+{
+ if(!frs.readK(Header.FileSig, 32))
+ return false;
+
+ if(!frs.readK(&Header.MajorVersion, sizeof(Header.MajorVersion)))
+ return false;
+
+ if(!frs.readK(&Header.MinorVersion, sizeof(Header.MinorVersion)))
+ return false;
+
+ return true;
+}
+
+bool fmt_codec::iCheckPsp()
+{
+ if (strcmp(Header.FileSig, "Paint Shop Pro Image File\n\x1a")) // "i"
+ return false;
+ if (Header.MajorVersion < 3 || Header.MajorVersion > 5)
+ return false;
+ if (Header.MinorVersion != 0)
+ return false;
+
+ return true;
+}
+
+bool fmt_codec::ReadGenAttributes()
+{
+ BLOCKHEAD AttHead;
+ ILint Padding;
+ ILuint ChunkLen;
+
+ if(!frs.readK(&AttHead, sizeof(AttHead)))
+ return false;
+
+ if (AttHead.HeadID[0] != 0x7E || AttHead.HeadID[1] != 0x42 || AttHead.HeadID[2] != 0x4B || AttHead.HeadID[3] != 0x00)
+ return false;
+
+ if (AttHead.BlockID != PSP_IMAGE_BLOCK)
+ return false;
+
+ if(!frs.readK(&ChunkLen, sizeof(ChunkLen)))
+ return false;
+
+ if (Header.MajorVersion != 3)
+ ChunkLen -= 4;
+
+ if (!frs.readK(&AttChunk, std::min(sizeof(AttChunk), size_t(ChunkLen))))
+ return false;
+
+ // Can have new entries in newer versions of the spec (4.0).
+ Padding = (ChunkLen) - sizeof(AttChunk);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+
+ // @TODO: Anything but 24 not supported yet...
+ if (AttChunk.BitDepth != 24 && AttChunk.BitDepth != 8)
+ return false;
+
+ // @TODO; Add support for compression...
+ if (AttChunk.Compression != PSP_COMP_NONE && AttChunk.Compression != PSP_COMP_RLE)
+ return false;
+
+ // @TODO: Check more things in the general attributes chunk here.
+ return true;
+}
+
+bool fmt_codec::ParseChunks()
+{
+ BLOCKHEAD Block;
+ size_t Pos;
+
+ do {
+ if (!frs.readK(&Block, sizeof(Block)))
+ return true;
+
+ if (Header.MajorVersion == 3)
+ frs.readK(&Block.BlockLen, sizeof(Block.BlockLen));
+
+ if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00)
+ return true;
+
+ Pos = frs.tellg();
+
+ switch (Block.BlockID)
+ {
+ case PSP_LAYER_START_BLOCK:
+ if (!ReadLayerBlock())
+ return false;
+ break;
+
+ case PSP_ALPHA_BANK_BLOCK:
+ if (!ReadAlphaBlock())
+ return false;
+ break;
+
+ case PSP_COLOR_BLOCK:
+ if (!ReadPalette())
+ return false;
+ break;
+ }
+
+ // Skip to next block just in case we didn't read the entire block.
+ frs.seekg(Pos + Block.BlockLen, ios::beg);
+
+ }
+ while (1);
+
+ return true;
+}
+
+bool fmt_codec::ReadLayerBlock()
+{
+ BLOCKHEAD Block;
+ LAYERINFO_CHUNK LayerInfo;
+ LAYERBITMAP_CHUNK Bitmap;
+ ILuint ChunkSize, Padding, i;
+ ILushort NumChars;
+
+ // Layer sub-block header
+ if (!frs.readK(&Block, sizeof(Block)))
+ return false;
+
+ if(Header.MajorVersion == 3)
+ frs.readK(&Block.BlockLen, sizeof(Block.BlockLen));
+
+ if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00)
+ return false;
+
+ if (Block.BlockID != PSP_LAYER_BLOCK)
+ return false;
+
+ if (Header.MajorVersion == 3)
+ {
+ frs.seekg(256, ios::cur); // We don't care about the name of the layer.
+ frs.readK(&LayerInfo, sizeof(LayerInfo));
+
+ if(!frs.readK(&Bitmap, sizeof(Bitmap)))
+ return false;
+ }
+ else
+ { // Header.MajorVersion >= 4
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+ frs.readK(&NumChars, sizeof(NumChars));
+ frs.seekg(NumChars, ios::cur); // We don't care about the layer's name.
+
+ ChunkSize -= (2 + 4 + NumChars);
+
+ if (!frs.readK(&LayerInfo, std::min(sizeof(LayerInfo), size_t(ChunkSize))))
+ return false;
+
+ // Can have new entries in newer versions of the spec (5.0).
+ Padding = (ChunkSize) - sizeof(LayerInfo);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+
+ if (!frs.readK(&Bitmap, sizeof(Bitmap)))
+ return false;
+
+ Padding = (ChunkSize - 4) - sizeof(Bitmap);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+
+ Channels = new ILubyte* [Bitmap.NumChannels];
+
+ if (!Channels)
+ return false;
+
+ NumChannels = Bitmap.NumChannels;
+
+ for (i = 0; i < NumChannels; i++)
+ Channels[i] = 0;
+
+ for (i = 0; i < NumChannels; i++)
+ {
+ Channels[i] = GetChannel();
+
+ if(!Channels[i])
+ return false;
+ }
+
+ return true;
+}
+
+bool fmt_codec::ReadAlphaBlock()
+{
+ BLOCKHEAD Block;
+ ALPHAINFO_CHUNK AlphaInfo;
+ ALPHA_CHUNK AlphaChunk;
+ ILushort NumAlpha, StringSize;
+ ILuint ChunkSize, Padding;
+
+ if (Header.MajorVersion == 3) {
+ frs.readK(&NumAlpha, sizeof(NumAlpha));
+ }
+ else {
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+ frs.readK(&NumAlpha, sizeof(NumAlpha));
+
+ Padding = (ChunkSize - 4 - 2);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+
+ // Alpha channel header
+ if (!frs.readK(&Block, sizeof(Block)))
+ return false;
+
+ if (Header.MajorVersion == 3)
+ frs.readK(&Block.BlockLen, sizeof(Block.BlockLen));
+
+ if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
+ Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
+ return false;
+ }
+ if (Block.BlockID != PSP_ALPHA_CHANNEL_BLOCK)
+ return false;
+
+ if (Header.MajorVersion >= 4)
+ {
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+ frs.readK(&StringSize, sizeof(StringSize));
+
+ frs.seekg(StringSize, ios::cur);
+
+ if (!frs.readK(&AlphaInfo, sizeof(AlphaInfo)))
+ return false;
+
+ Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo));
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+
+ if (!frs.readK(&AlphaChunk, sizeof(AlphaChunk)))
+ return false;
+
+ Padding = (ChunkSize - 4 - sizeof(AlphaChunk));
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+ else {
+ frs.seekg(256, ios::cur);
+ frs.readK(&AlphaInfo, sizeof(AlphaInfo));
+
+ if(!frs.readK(&AlphaChunk, sizeof(AlphaChunk)))
+ return false;
+ }
+
+ Alpha = GetChannel();
+
+ if (!Alpha)
+ return false;
+
+ return true;
+}
+
+ILubyte *fmt_codec::GetChannel()
+{
+ BLOCKHEAD Block;
+ CHANNEL_CHUNK Channel;
+ ILubyte *CompData = 0, *Data = 0;
+ ILuint ChunkSize, Padding;
+
+ if (!frs.readK(&Block, sizeof(Block)))
+ return 0;
+
+ if (Header.MajorVersion == 3)
+ frs.readK(&Block.BlockLen, sizeof(Block.BlockLen));
+
+ if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00)
+ return 0;
+
+ if (Block.BlockID != PSP_CHANNEL_BLOCK)
+ return 0;
+
+ if (Header.MajorVersion >= 4)
+ {
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+
+ if (!frs.readK(&Channel, sizeof(Channel)))
+ return 0;
+
+ Padding = (ChunkSize - 4) - sizeof(Channel);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+ else
+ {
+ if (!frs.readK(&Channel, sizeof(Channel)))
+ return 0;
+ }
+
+ CompData = new ILubyte [Channel.CompLen];
+
+ if (!CompData)
+ return 0;
+
+ if (!frs.readK(CompData, Channel.CompLen))
+ {
+ delete CompData;
+ return 0;
+ }
+
+ if(AttChunk.Compression != PSP_COMP_NONE)
+ {
+ Data = new ILubyte [AttChunk.Width * AttChunk.Height];
+
+ if (!Data)
+ {
+ delete CompData;
+ return 0;
+ }
+ }
+
+ switch (AttChunk.Compression)
+ {
+ case PSP_COMP_NONE:
+ return CompData;
+
+ case PSP_COMP_RLE:
+ if (!UncompRLE(CompData, Data, Channel.CompLen))
+ {
+ delete Data;
+ delete CompData;
+ return 0;
+ }
+ break;
+
+ default:
+ delete Data;
+ delete CompData;
+ return 0;
+ }
+
+ delete CompData;
+
+ return Data;
+}
+
+bool fmt_codec::UncompRLE(ILubyte *CompData, ILubyte *Data, ILuint CompLen)
+{
+ ILubyte Run, Colour;
+ ILint i, Count;
+
+ for (i = 0, Count = 0; i < (ILint)CompLen; ) {
+ Run = *CompData++;
+ i++;
+ if (Run > 128) {
+ Run -= 128;
+ Colour = *CompData++;
+ i++;
+ memset(Data, Colour, Run);
+ }
+ else {
+ memcpy(Data, CompData, Run);
+ CompData += Run;
+ i += Run;
+ }
+ Data += Run;
+ Count += Run;
+ }
+
+ return true;
+}
+
+bool fmt_codec::ReadPalette()
+{
+ ILuint ChunkSize, PalCount, Padding;
+ RGBA rgba;
+
+ if (Header.MajorVersion >= 4)
+ {
+ frs.readK(&ChunkSize, sizeof(ChunkSize));
+ frs.readK(&PalCount, sizeof(PalCount));
+
+ Padding = (ChunkSize - 4 - 4);
+
+ if (Padding > 0)
+ frs.seekg(Padding, ios::cur);
+ }
+ else
+ frs.readK(&PalCount, sizeof(PalCount));
+
+ pal = new RGBA [PalCount];
+
+ if(!pal)
+ return false;
+
+ RGBA *ppal = pal;
+
+ for(u32 i = 0;i < PalCount;i++)
+ {
+ if(!frs.readK(&rgba, sizeof(RGBA)))
+ return false;
+
+ ppal->r = rgba.b;
+ ppal->g = rgba.g;
+ ppal->b = rgba.r;
+ ppal->a = rgba.a;
+
+ ppal++;
+ }
+
+ return true;
+}
+
+/******************** ksquirrel-libs stuff ****************************/
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ Channels = 0;
+ Alpha = 0;
+ pal = 0;
+
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+ finfo.animated = false;
+
+ if(!iGetPspHead())
+ return SQE_R_BADFILE;
+
+ if(!iCheckPsp())
+ return SQE_R_BADFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ if(!ReadGenAttributes())
+ return SQE_R_BADFILE;
+
+ if(!ParseChunks())
+ return SQE_R_BADFILE;
+
+// if(!AssembleImage())
+// return SQE_R_BADFILE;
+
+ fmt_image image;
+
+ image.w = AttChunk.Width;
+ image.h = AttChunk.Height;
+ image.compression = (AttChunk.Compression == PSP_COMP_RLE ? "RLE" : "-");
+ image.bpp = (NumChannels == 1 ? 8 : ((Alpha || NumChannels == 4) ? 32 : 24));
+ image.colorspace = fmt_utils::colorSpaceByBpp(image.bpp);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ line = -1;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ line++;
+
+ fmt_image *im = image(currentImage);
+
+ u32 i, j;
+ u32 ifrom = line * im->w;
+ u32 ito = ifrom + im->w;
+
+ if (NumChannels == 1)
+ {
+ memset(scan, 0, im->w * sizeof(RGBA));
+
+ for (i = ifrom, j = 0; i < ito; i++, j++)
+ {
+ scan[j] = pal[Channels[0][i]];
+ scan[j].a = 255;
+ }
+ }
+ else
+ {
+ if (Alpha)
+ {
+ memset(scan, 0, im->w * sizeof(RGBA));
+ u8 *data = (u8 *)scan;
+
+ for (i = ifrom, j = 0; i < ito; i++, j += 4)
+ {
+ data[j ] = Channels[0][i];
+ data[j+1] = Channels[1][i];
+ data[j+2] = Channels[2][i];
+ data[j+3] = Alpha[i];
+ }
+ }
+ // 3 channels, or 4 without alpha
+ else if (NumChannels == 3 || NumChannels == 4)
+ {
+ memset(scan, 0, im->w * sizeof(RGBA));
+ u8 *data = (u8 *)scan;
+
+ for (i = ifrom, j = 0; i < ito; i++, j += 4)
+ {
+ data[j ] = Channels[0][i];
+ data[j+1] = Channels[1][i];
+ data[j+2] = Channels[2][i];
+ data[j+3] = 255;
+ }
+ }
+ else
+ return SQE_R_BADFILE;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ if(Channels)
+ {
+ for (u32 i = 0; i < NumChannels; i++)
+ delete Channels[i];
+
+ delete Channels;
+ }
+
+ delete Alpha;
+ delete pal;
+
+ Channels = 0;
+ Alpha = 0;
+ pal = 0;
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_psp/fmt_codec_psp_defs.h b/kernel/kls_psp/fmt_codec_psp_defs.h
new file mode 100644
index 0000000..a03410e
--- /dev/null
+++ b/kernel/kls_psp/fmt_codec_psp_defs.h
@@ -0,0 +1,249 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_psp
+#define KSQUIRREL_CODEC_DEFS_psp
+
+static const u8 PSPSignature[32] =
+{
+ 0x50, 0x61, 0x69, 0x6E, 0x74, 0x20, 0x53, 0x68, 0x6F, 0x70, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x49,
+ 0x6D, 0x61, 0x67, 0x65, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x0A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const u8 GenAttHead[4] = { 0x7E, 0x42, 0x4B, 0x00 };
+
+typedef u8 ILubyte;
+typedef u16 ILushort;
+typedef u32 ILuint;
+typedef s32 ILint;
+typedef double ILdouble;
+
+//-----------------------------------------------------------------------------
+//
+// ImageLib Sources
+// Copyright (C) 2000-2002 by Denton Woods
+// Last modified: 05/02/2002 <--Y2K Compliant! =]
+//
+// Filename: src-IL/include/il_psp.h
+//
+// Description: Reads a Paint Shop Pro file.
+//
+//-----------------------------------------------------------------------------
+
+
+// Block identifiers
+enum PSPBlockID {
+ PSP_IMAGE_BLOCK = 0, // (0) General Image Attributes Block (main)
+ PSP_CREATOR_BLOCK, // (1) Creator Data Block (main)
+ PSP_COLOR_BLOCK, // (2) Color Palette Block (main and sub)
+ PSP_LAYER_START_BLOCK, // (3) Layer Bank Block (main)
+ PSP_LAYER_BLOCK, // (4) Layer Block (sub)
+ PSP_CHANNEL_BLOCK, // (5) Channel Block (sub)
+ PSP_SELECTION_BLOCK, // (6) Selection Block (main)
+ PSP_ALPHA_BANK_BLOCK, // (7) Alpha Bank Block (main)
+ PSP_ALPHA_CHANNEL_BLOCK, // (8) Alpha Channel Block (sub)
+ PSP_COMPOSITE_IMAGE_BLOCK, // (9) Composite Image Block (sub)
+ PSP_EXTENDED_DATA_BLOCK, // (10) Extended Data Block (main)
+ PSP_TUBE_BLOCK, // (11) Picture Tube Data Block (main)
+ PSP_ADJUSTMENT_EXTENSION_BLOCK, // (12) Adjustment Layer Block (sub)
+ PSP_VECTOR_EXTENSION_BLOCK, // (13) Vector Layer Block (sub)
+ PSP_SHAPE_BLOCK, // (14) Vector Shape Block (sub)
+ PSP_PAINTSTYLE_BLOCK, // (15) Paint Style Block (sub)
+ PSP_COMPOSITE_IMAGE_BANK_BLOCK, // (16) Composite Image Bank (main)
+ PSP_COMPOSITE_ATTRIBUTES_BLOCK, // (17) Composite Image Attr. (sub)
+ PSP_JPEG_BLOCK, // (18) JPEG Image Block (sub)
+ PSP_LINESTYLE_BLOCK, // (19) Line Style Block (sub)
+ PSP_TABLE_BANK_BLOCK, // (20) Table Bank Block (main)
+ PSP_TABLE_BLOCK, // (21) Table Block (sub)
+ PSP_PAPER_BLOCK, // (22) Vector Table Paper Block (sub)
+ PSP_PATTERN_BLOCK, // (23) Vector Table Pattern Block (sub)
+};
+
+
+// Bitmap type
+enum PSPDIBType {
+ PSP_DIB_IMAGE = 0, // Layer color bitmap
+ PSP_DIB_TRANS_MASK, // Layer transparency mask bitmap
+ PSP_DIB_USER_MASK, // Layer user mask bitmap
+ PSP_DIB_SELECTION, // Selection mask bitmap
+ PSP_DIB_ALPHA_MASK, // Alpha channel mask bitmap
+ PSP_DIB_THUMBNAIL // Thumbnail bitmap
+};
+
+// Channel types
+enum PSPChannelType {
+ PSP_CHANNEL_COMPOSITE = 0, // Channel of single channel bitmap
+ PSP_CHANNEL_RED, // Red channel of 24 bit bitmap
+ PSP_CHANNEL_GREEN, // Green channel of 24 bit bitmap
+ PSP_CHANNEL_BLUE // Blue channel of 24 bit bitmap
+};
+
+// Possible metrics used to measure resolution
+enum PSP_METRIC {
+ PSP_METRIC_UNDEFINED = 0, // Metric unknown
+ PSP_METRIC_INCH, // Resolution is in inches
+ PSP_METRIC_CM // Resolution is in centimeters
+};
+
+
+// Possible types of compression.
+enum PSPCompression {
+ PSP_COMP_NONE = 0, // No compression
+ PSP_COMP_RLE, // RLE compression
+ PSP_COMP_LZ77, // LZ77 compression
+ PSP_COMP_JPEG // JPEG compression (only used by thumbnail and composite image)
+};
+
+// Picture tube placement mode.
+enum TubePlacementMode {
+ tpmRandom, // Place tube images in random intervals
+ tpmConstant // Place tube images in constant intervals
+};
+
+// Picture tube selection mode.
+enum TubeSelectionMode {
+ tsmRandom, // Randomly select the next image in tube to display
+ tsmIncremental, // Select each tube image in turn
+ tsmAngular, // Select image based on cursor direction
+ tsmPressure, // Select image based on pressure (from pressure-sensitive pad)
+ tsmVelocity // Select image based on cursor speed
+};
+
+// Extended data field types.
+enum PSPExtendedDataID {
+ PSP_XDATA_TRNS_INDEX = 0 // Transparency index field
+};
+
+// Creator field types.
+enum PSPCreatorFieldID {
+ PSP_CRTR_FLD_TITLE = 0, // Image document title field
+ PSP_CRTR_FLD_CRT_DATE, // Creation date field
+ PSP_CRTR_FLD_MOD_DATE, // Modification date field
+ PSP_CRTR_FLD_ARTIST, // Artist name field
+ PSP_CRTR_FLD_CPYRGHT, // Copyright holder name field
+ PSP_CRTR_FLD_DESC, // Image document description field
+ PSP_CRTR_FLD_APP_ID, // Creating app id field
+ PSP_CRTR_FLD_APP_VER, // Creating app version field
+};
+
+// Creator application identifiers.
+enum PSPCreatorAppID {
+ PSP_CREATOR_APP_UNKNOWN = 0, // Creator application unknown
+ PSP_CREATOR_APP_PAINT_SHOP_PRO // Creator is Paint Shop Pro
+};
+
+// Layer types.
+enum PSPLayerType {
+ PSP_LAYER_NORMAL = 0, // Normal layer
+ PSP_LAYER_FLOATING_SELECTION // Floating selection layer
+};
+
+struct PSPRECT
+{
+ ILuint x1,y1,x2,y2;
+} PACKED;
+
+struct PSPHEAD
+{
+ char FileSig[32];
+ ILushort MajorVersion;
+ ILushort MinorVersion;
+} PACKED;
+
+struct BLOCKHEAD
+{
+ ILubyte HeadID[4];
+ ILushort BlockID;
+ ILuint BlockLen;
+} PACKED;
+
+struct GENATT_CHUNK
+{
+ ILint Width;
+ ILint Height;
+ ILdouble Resolution;
+ ILubyte ResMetric;
+ ILushort Compression;
+ ILushort BitDepth;
+ ILushort PlaneCount;
+ ILuint ColourCount;
+ ILubyte GreyscaleFlag;
+ ILuint SizeOfImage;
+ ILint ActiveLayer;
+ ILushort LayerCount;
+ ILuint GraphicContents;
+} PACKED;
+
+struct LAYERINFO_CHUNK
+{
+ ILubyte LayerType;
+ PSPRECT ImageRect;
+ PSPRECT SavedImageRect;
+ ILubyte Opacity;
+ ILubyte BlendingMode;
+ ILubyte LayerFlags;
+ ILubyte TransProtFlag;
+ ILubyte LinkID;
+ PSPRECT MaskRect;
+ PSPRECT SavedMaskRect;
+ ILubyte MaskLinked;
+ ILubyte MaskDisabled;
+ ILubyte InvertMaskBlend;
+ ILushort BlendRange;
+ ILubyte SourceBlend1[4];
+ ILubyte DestBlend1[4];
+ ILubyte SourceBlend2[4];
+ ILubyte DestBlend2[4];
+ ILubyte SourceBlend3[4];
+ ILubyte DestBlend3[4];
+ ILubyte SourceBlend4[4];
+ ILubyte DestBlend4[4];
+ ILubyte SourceBlend5[4];
+ ILubyte DestBlend5[4];
+} PACKED;
+
+struct LAYERBITMAP_CHUNK
+{
+ ILushort NumBitmaps;
+ ILushort NumChannels;
+} PACKED;
+
+struct CHANNEL_CHUNK
+{
+ ILuint CompLen;
+ ILuint Length;
+ ILushort BitmapType;
+ ILushort ChanType;
+} PACKED;
+
+struct ALPHAINFO_CHUNK
+{
+ PSPRECT AlphaRect;
+ PSPRECT AlphaSavedRect;
+} PACKED;
+
+struct ALPHA_CHUNK
+{
+ ILushort BitmapCount;
+ ILushort ChannelCount;
+} PACKED;
+
+#endif