| 1 |
/* |
| 2 |
|
| 3 |
generate_image.c - Part of psiconv, a PSION 5 file formats converter |
| 4 |
Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl> |
| 5 |
|
| 6 |
This program is free software; you can redistribute it and/or modify |
| 7 |
it under the terms of the GNU General Public License as published by |
| 8 |
the Free Software Foundation; either version 2 of the License, or |
| 9 |
(at your option) any later version. |
| 10 |
|
| 11 |
This program is distributed in the hope that it will be useful, |
| 12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 |
GNU General Public License for more details. |
| 15 |
|
| 16 |
You should have received a copy of the GNU General Public License |
| 17 |
along with this program; if not, write to the Free Software |
| 18 |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 19 |
*/ |
| 20 |
|
| 21 |
#include "config.h" |
| 22 |
#include "compat.h" |
| 23 |
|
| 24 |
#include "generate_routines.h" |
| 25 |
#include "error.h" |
| 26 |
#include "list.h" |
| 27 |
|
| 28 |
#ifdef DMALLOC |
| 29 |
#include <dmalloc.h> |
| 30 |
#endif |
| 31 |
|
| 32 |
typedef psiconv_list psiconv_pixel_bytes; /* psiconv_u8 */ |
| 33 |
|
| 34 |
typedef psiconv_list psiconv_pixel_ints; /* of psiconv_u32 */ |
| 35 |
|
| 36 |
typedef struct psiconv_pixel_float_s |
| 37 |
{ |
| 38 |
psiconv_u32 length; |
| 39 |
float *red; |
| 40 |
float *green; |
| 41 |
float *blue; |
| 42 |
} psiconv_pixel_floats_t; |
| 43 |
|
| 44 |
static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels, |
| 45 |
int xsize,int ysize, |
| 46 |
const psiconv_pixel_floats_t data, |
| 47 |
int colordepth,int color, |
| 48 |
int redbits,int greenbits,int bluebits, |
| 49 |
const psiconv_pixel_floats_t palet); |
| 50 |
static int psiconv_pixel_data_to_bytes(const psiconv_config config, |
| 51 |
psiconv_pixel_bytes *bytes, int xsize, |
| 52 |
int ysize, const psiconv_pixel_ints pixels, |
| 53 |
int colordepth); |
| 54 |
static int psiconv_encode_rle8(const psiconv_config config, |
| 55 |
const psiconv_pixel_bytes plain_bytes, |
| 56 |
psiconv_pixel_bytes *encoded_bytes); |
| 57 |
static int psiconv_encode_rle12(const psiconv_config config, |
| 58 |
const psiconv_pixel_bytes plain_bytes, |
| 59 |
psiconv_pixel_bytes *encoded_bytes); |
| 60 |
static int psiconv_encode_rle16(const psiconv_config config, |
| 61 |
const psiconv_pixel_bytes plain_bytes, |
| 62 |
psiconv_pixel_bytes *encoded_bytes); |
| 63 |
static int psiconv_encode_rle24(const psiconv_config config, |
| 64 |
const psiconv_pixel_bytes plain_bytes, |
| 65 |
psiconv_pixel_bytes *encoded_bytes); |
| 66 |
|
| 67 |
#define PALET_NONE_LEN 0 |
| 68 |
|
| 69 |
psiconv_pixel_floats_t palet_none = |
| 70 |
{ |
| 71 |
PALET_NONE_LEN, |
| 72 |
NULL, |
| 73 |
NULL, |
| 74 |
NULL |
| 75 |
}; |
| 76 |
|
| 77 |
#define PALET_COLOR_4_LEN 16 |
| 78 |
float palet_color_4_red[PALET_COLOR_4_LEN] = |
| 79 |
{ 0x00/256.0, 0x55/256.0, 0x80/256.0, 0x80/256.0, /* 0x00 */ |
| 80 |
0x00/256.0, 0xff/256.0, 0x00/256.0, 0xff/256.0, /* 0x04 */ |
| 81 |
0xff/256.0, 0x00/256.0, 0x00/256.0, 0x80/256.0, /* 0x08 */ |
| 82 |
0x00/256.0, 0x00/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */ |
| 83 |
}; |
| 84 |
|
| 85 |
float palet_color_4_green[PALET_COLOR_4_LEN] = |
| 86 |
{ 0x00/256.0, 0x55/256.0, 0x00/256.0, 0x80/256.0, /* 0x00 */ |
| 87 |
0x80/256.0, 0x00/256.0, 0xff/256.0, 0xff/256.0, /* 0x04 */ |
| 88 |
0x00/256.0, 0xff/256.0, 0xff/256.0, 0x00/256.0, /* 0x08 */ |
| 89 |
0x00/256.0, 0x80/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */ |
| 90 |
}; |
| 91 |
|
| 92 |
float palet_color_4_blue[PALET_COLOR_4_LEN] = |
| 93 |
{ 0x00/256.0, 0x55/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */ |
| 94 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x04 */ |
| 95 |
0xff/256.0, 0x00/256.0, 0xff/256.0, 0x80/256.0, /* 0x08 */ |
| 96 |
0x80/256.0, 0x80/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */ |
| 97 |
}; |
| 98 |
|
| 99 |
psiconv_pixel_floats_t palet_color_4 = |
| 100 |
{ |
| 101 |
PALET_COLOR_4_LEN, |
| 102 |
palet_color_4_red, |
| 103 |
palet_color_4_green, |
| 104 |
palet_color_4_blue, |
| 105 |
}; |
| 106 |
|
| 107 |
#define PALET_COLOR_8_LEN 256 |
| 108 |
float palet_color_8_red[PALET_COLOR_8_LEN] = |
| 109 |
{ 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x00 */ |
| 110 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x04 */ |
| 111 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x08 */ |
| 112 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x0c */ |
| 113 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x10 */ |
| 114 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x14 */ |
| 115 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x18 */ |
| 116 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x1c */ |
| 117 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x20 */ |
| 118 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x24 */ |
| 119 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x28 */ |
| 120 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x2c */ |
| 121 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x30 */ |
| 122 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x34 */ |
| 123 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x38 */ |
| 124 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x3c */ |
| 125 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x40 */ |
| 126 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x44 */ |
| 127 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x48 */ |
| 128 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x4c */ |
| 129 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x50 */ |
| 130 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x54 */ |
| 131 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x58 */ |
| 132 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x5c */ |
| 133 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x60 */ |
| 134 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x64 */ |
| 135 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x68 */ |
| 136 |
0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */ |
| 137 |
0x77/256.0, 0x11/256.0, 0x22/256.0, 0x44/256.0, /* 0x70 */ |
| 138 |
0x55/256.0, 0x77/256.0, 0x00/256.0, 0x00/256.0, /* 0x74 */ |
| 139 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x78 */ |
| 140 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x7c */ |
| 141 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x80 */ |
| 142 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x84 */ |
| 143 |
0x00/256.0, 0x00/256.0, 0x88/256.0, 0xaa/256.0, /* 0x88 */ |
| 144 |
0xbb/256.0, 0xdd/256.0, 0xee/256.0, 0x88/256.0, /* 0x8c */ |
| 145 |
0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */ |
| 146 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x94 */ |
| 147 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x98 */ |
| 148 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x9c */ |
| 149 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xa0 */ |
| 150 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xa4 */ |
| 151 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xa8 */ |
| 152 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xac */ |
| 153 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xb0 */ |
| 154 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xb4 */ |
| 155 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xb8 */ |
| 156 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xbc */ |
| 157 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xc0 */ |
| 158 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xc4 */ |
| 159 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xc8 */ |
| 160 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xcc */ |
| 161 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xd0 */ |
| 162 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xd4 */ |
| 163 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xd8 */ |
| 164 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xdc */ |
| 165 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xe0 */ |
| 166 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xe4 */ |
| 167 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xe8 */ |
| 168 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xec */ |
| 169 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xf0 */ |
| 170 |
0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xf4 */ |
| 171 |
0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xf8 */ |
| 172 |
0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0 /* 0xfc */ |
| 173 |
}; |
| 174 |
|
| 175 |
float palet_color_8_green[PALET_COLOR_8_LEN] = |
| 176 |
{ 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */ |
| 177 |
0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x04 */ |
| 178 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x08 */ |
| 179 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x0c */ |
| 180 |
0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x10 */ |
| 181 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x14 */ |
| 182 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x18 */ |
| 183 |
0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x1c */ |
| 184 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x20 */ |
| 185 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x24 */ |
| 186 |
0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x28 */ |
| 187 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x2c */ |
| 188 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x30 */ |
| 189 |
0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x34 */ |
| 190 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x38 */ |
| 191 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x3c */ |
| 192 |
0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x40 */ |
| 193 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x44 */ |
| 194 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x48 */ |
| 195 |
0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x4c */ |
| 196 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x50 */ |
| 197 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x54 */ |
| 198 |
0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x58 */ |
| 199 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x5c */ |
| 200 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x60 */ |
| 201 |
0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x64 */ |
| 202 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x68 */ |
| 203 |
0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */ |
| 204 |
0x77/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x70 */ |
| 205 |
0x00/256.0, 0x00/256.0, 0x11/256.0, 0x22/256.0, /* 0x74 */ |
| 206 |
0x44/256.0, 0x55/256.0, 0x77/256.0, 0x00/256.0, /* 0x78 */ |
| 207 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x7c */ |
| 208 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x80 */ |
| 209 |
0x00/256.0, 0x88/256.0, 0xaa/256.0, 0xbb/256.0, /* 0x84 */ |
| 210 |
0xdd/256.0, 0xee/256.0, 0x00/256.0, 0x00/256.0, /* 0x88 */ |
| 211 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x88/256.0, /* 0x8c */ |
| 212 |
0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */ |
| 213 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x94 */ |
| 214 |
0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x98 */ |
| 215 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x9c */ |
| 216 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xa0 */ |
| 217 |
0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xa4 */ |
| 218 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa8 */ |
| 219 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xac */ |
| 220 |
0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xb0 */ |
| 221 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xb4 */ |
| 222 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0xb8 */ |
| 223 |
0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0xbc */ |
| 224 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0xc0 */ |
| 225 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xc4 */ |
| 226 |
0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xc8 */ |
| 227 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xcc */ |
| 228 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd0 */ |
| 229 |
0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xd4 */ |
| 230 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xd8 */ |
| 231 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0xdc */ |
| 232 |
0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0xe0 */ |
| 233 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0xe4 */ |
| 234 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xe8 */ |
| 235 |
0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xec */ |
| 236 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xf0 */ |
| 237 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xf4 */ |
| 238 |
0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xf8 */ |
| 239 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xfc */ |
| 240 |
}; |
| 241 |
|
| 242 |
float palet_color_8_blue[PALET_COLOR_8_LEN] = |
| 243 |
{ 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */ |
| 244 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x04 */ |
| 245 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x08 */ |
| 246 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x0c */ |
| 247 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x10 */ |
| 248 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x14 */ |
| 249 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x18 */ |
| 250 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x1c */ |
| 251 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x20 */ |
| 252 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x24 */ |
| 253 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x28 */ |
| 254 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x2c */ |
| 255 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x30 */ |
| 256 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x34 */ |
| 257 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x38 */ |
| 258 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x3c */ |
| 259 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x40 */ |
| 260 |
0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x44 */ |
| 261 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x48 */ |
| 262 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x4c */ |
| 263 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x50 */ |
| 264 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x54 */ |
| 265 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x58 */ |
| 266 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x5c */ |
| 267 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x60 */ |
| 268 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x64 */ |
| 269 |
0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x68 */ |
| 270 |
0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */ |
| 271 |
0x77/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x70 */ |
| 272 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x74 */ |
| 273 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x11/256.0, /* 0x78 */ |
| 274 |
0x22/256.0, 0x44/256.0, 0x55/256.0, 0x77/256.0, /* 0x7c */ |
| 275 |
0x88/256.0, 0xaa/256.0, 0xbb/256.0, 0xdd/256.0, /* 0x80 */ |
| 276 |
0xee/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x84 */ |
| 277 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x88 */ |
| 278 |
0x00/256.0, 0x00/256.0, 0x00/256.0, 0x88/256.0, /* 0x8c */ |
| 279 |
0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */ |
| 280 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x94 */ |
| 281 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x98 */ |
| 282 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x9c */ |
| 283 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa0 */ |
| 284 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa4 */ |
| 285 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa8 */ |
| 286 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xac */ |
| 287 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xb0 */ |
| 288 |
0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xb4 */ |
| 289 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xb8 */ |
| 290 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xbc */ |
| 291 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc0 */ |
| 292 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc4 */ |
| 293 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc8 */ |
| 294 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xcc */ |
| 295 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd0 */ |
| 296 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd4 */ |
| 297 |
0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd8 */ |
| 298 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xdc */ |
| 299 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe0 */ |
| 300 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe4 */ |
| 301 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe8 */ |
| 302 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xec */ |
| 303 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf0 */ |
| 304 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf4 */ |
| 305 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf8 */ |
| 306 |
0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xfc */ |
| 307 |
}; |
| 308 |
|
| 309 |
psiconv_pixel_floats_t palet_color_8 = |
| 310 |
{ |
| 311 |
PALET_COLOR_8_LEN, |
| 312 |
palet_color_8_red, |
| 313 |
palet_color_8_green, |
| 314 |
palet_color_8_blue, |
| 315 |
}; |
| 316 |
|
| 317 |
int psiconv_write_paint_data_section(const psiconv_config config, |
| 318 |
psiconv_buffer buf, |
| 319 |
const psiconv_paint_data_section value, |
| 320 |
int is_clipart) |
| 321 |
{ |
| 322 |
int res,colordepth,i; |
| 323 |
psiconv_pixel_ints ints; |
| 324 |
psiconv_pixel_floats_t floats,palet; |
| 325 |
psiconv_list bytes,bytes_rle; |
| 326 |
psiconv_u8 *byteptr,encoding; |
| 327 |
|
| 328 |
/* First, we check whether we can cope with the current configuration. |
| 329 |
If not, we stop at once */ |
| 330 |
if ((config->colordepth != 2) && (config->colordepth != 4) && |
| 331 |
(config->colordepth != 8) && (config->colordepth != 12) && |
| 332 |
(config->colordepth != 16) && (config->colordepth != 24)) { |
| 333 |
psiconv_warn(config,0,psiconv_buffer_length(buf), |
| 334 |
"Unsupported color depth (%d); try 2, 4, 8, 16 or 24", |
| 335 |
config->colordepth); |
| 336 |
res = -PSICONV_E_GENERATE; |
| 337 |
goto ERROR1; |
| 338 |
} |
| 339 |
|
| 340 |
if ((config->color) && |
| 341 |
(config->bluebits || config->redbits || config->greenbits) && |
| 342 |
(config->bluebits+config->redbits+config->greenbits!=config->colordepth)) { |
| 343 |
psiconv_warn(config,0,psiconv_buffer_length(buf), |
| 344 |
"Sum of red (%d), green (%d) and blue (%d) bits should be " |
| 345 |
"equal to the color depth (%d)", |
| 346 |
config->redbits,config->greenbits,config->bluebits, |
| 347 |
config->colordepth); |
| 348 |
res = -PSICONV_E_GENERATE; |
| 349 |
goto ERROR1; |
| 350 |
} |
| 351 |
|
| 352 |
if (config->color && |
| 353 |
!(config->redbits || config->greenbits || config->bluebits) && |
| 354 |
(config->colordepth != 4) && (config->colordepth != 8)) { |
| 355 |
psiconv_warn(config,0,psiconv_buffer_length(buf), |
| 356 |
"Current color depth (%d) has no palet associated with it", |
| 357 |
config->colordepth); |
| 358 |
res = -PSICONV_E_GENERATE; |
| 359 |
goto ERROR1; |
| 360 |
} |
| 361 |
|
| 362 |
if (config->color || (config->colordepth != 2)) |
| 363 |
psiconv_warn(config,0,psiconv_buffer_length(buf), |
| 364 |
"All image types except 2-bit greyscale are experimental!"); |
| 365 |
|
| 366 |
|
| 367 |
if (!value) { |
| 368 |
psiconv_warn(config,0,psiconv_buffer_length(buf),"Null paint data section"); |
| 369 |
res = -PSICONV_E_GENERATE; |
| 370 |
goto ERROR1; |
| 371 |
} |
| 372 |
|
| 373 |
floats.red = value->red; |
| 374 |
floats.green = value->green; |
| 375 |
floats.blue = value->blue; |
| 376 |
floats.length = value->xsize * value->ysize; |
| 377 |
|
| 378 |
palet = palet_none; |
| 379 |
if ((config->color) && (config->redbits == 0) && (config->greenbits == 0) &&\ |
| 380 |
(config->bluebits == 0)) |
| 381 |
switch (config->colordepth) { |
| 382 |
case 4: palet = palet_color_4; break; |
| 383 |
case 8: palet = palet_color_8; break; |
| 384 |
default: palet = palet_none; break; |
| 385 |
} |
| 386 |
|
| 387 |
if ((res = psiconv_collect_pixel_data(&ints,value->xsize, |
| 388 |
value->ysize,floats, |
| 389 |
config->colordepth,config->color, |
| 390 |
config->redbits,config->greenbits, |
| 391 |
config->bluebits,palet))) |
| 392 |
goto ERROR1; |
| 393 |
|
| 394 |
if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize, |
| 395 |
ints,config->colordepth))) |
| 396 |
goto ERROR2; |
| 397 |
|
| 398 |
|
| 399 |
switch (config->colordepth) { |
| 400 |
case 2: |
| 401 |
case 4: |
| 402 |
case 8: |
| 403 |
encoding = 0x01; |
| 404 |
if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle))) |
| 405 |
goto ERROR3; |
| 406 |
break; |
| 407 |
case 12: |
| 408 |
encoding = 0x02; |
| 409 |
if ((res = psiconv_encode_rle12(config,bytes,&bytes_rle))) |
| 410 |
goto ERROR3; |
| 411 |
break; |
| 412 |
case 16: |
| 413 |
encoding = 0x03; |
| 414 |
if ((res = psiconv_encode_rle16(config,bytes,&bytes_rle))) |
| 415 |
goto ERROR3; |
| 416 |
break; |
| 417 |
case 24: |
| 418 |
encoding = 0x04; |
| 419 |
if ((res = psiconv_encode_rle24(config,bytes,&bytes_rle))) |
| 420 |
goto ERROR3; |
| 421 |
break; |
| 422 |
default: |
| 423 |
encoding = 0x00; |
| 424 |
} |
| 425 |
if (encoding) { |
| 426 |
if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) { |
| 427 |
psiconv_list_free(bytes); |
| 428 |
bytes = bytes_rle; |
| 429 |
} else { |
| 430 |
psiconv_list_free(bytes_rle); |
| 431 |
encoding = 0x00; |
| 432 |
} |
| 433 |
} |
| 434 |
|
| 435 |
if ((res = psiconv_write_u32(config,buf, |
| 436 |
0x28+psiconv_list_length(bytes)))) |
| 437 |
goto ERROR3; |
| 438 |
if ((res = psiconv_write_u32(config,buf,0x28))) |
| 439 |
goto ERROR3; |
| 440 |
if ((res = psiconv_write_u32(config,buf,value->xsize))) |
| 441 |
goto ERROR3; |
| 442 |
if ((res = psiconv_write_u32(config,buf,value->ysize))) |
| 443 |
goto ERROR3; |
| 444 |
if ((res = psiconv_write_length(config,buf,value->pic_xsize))) |
| 445 |
goto ERROR3; |
| 446 |
if ((res = psiconv_write_length(config,buf,value->pic_ysize))) |
| 447 |
goto ERROR3; |
| 448 |
colordepth = config->colordepth; |
| 449 |
if ((res = psiconv_write_u32(config,buf,colordepth))) |
| 450 |
goto ERROR3; |
| 451 |
if ((res = psiconv_write_u32(config,buf,(config->color?1:0)))) |
| 452 |
goto ERROR3; |
| 453 |
if ((res = psiconv_write_u32(config,buf,0))) |
| 454 |
goto ERROR3; |
| 455 |
if ((res = psiconv_write_u32(config,buf,encoding))) |
| 456 |
goto ERROR3; |
| 457 |
if (is_clipart) { |
| 458 |
if ((res = psiconv_write_u32(config,buf,0xffffffff))) |
| 459 |
goto ERROR3; |
| 460 |
if ((res = psiconv_write_u32(config,buf,0x00000044))) |
| 461 |
goto ERROR3; |
| 462 |
} |
| 463 |
for (i = 0; i < psiconv_list_length(bytes); i++) { |
| 464 |
if (!(byteptr = psiconv_list_get(bytes,i))) |
| 465 |
goto ERROR3; |
| 466 |
if ((res = psiconv_write_u8(config,buf,*byteptr))) |
| 467 |
goto ERROR3; |
| 468 |
} |
| 469 |
|
| 470 |
ERROR3: |
| 471 |
psiconv_list_free(bytes); |
| 472 |
ERROR2: |
| 473 |
psiconv_list_free(ints); |
| 474 |
ERROR1: |
| 475 |
return res; |
| 476 |
} |
| 477 |
|
| 478 |
/* Translate the floating point RGB information into pixel values. |
| 479 |
The palet is optional; without it, we just use the |
| 480 |
colordepth. With a large palet this is not very fast, but it will do for |
| 481 |
now. For greyscale pictures, just use the palet. */ |
| 482 |
int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize, |
| 483 |
const psiconv_pixel_floats_t data, |
| 484 |
int colordepth,int color, |
| 485 |
int redbits,int bluebits,int greenbits, |
| 486 |
const psiconv_pixel_floats_t palet) |
| 487 |
{ |
| 488 |
int res,x,y,i; |
| 489 |
psiconv_u32 index,pixel; |
| 490 |
float p_red,p_green,p_blue,dist,new_dist; |
| 491 |
|
| 492 |
if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) { |
| 493 |
res = -PSICONV_E_NOMEM; |
| 494 |
goto ERROR1; |
| 495 |
} |
| 496 |
|
| 497 |
for (y = 0; y < ysize; y++) { |
| 498 |
for (x = 0; x < xsize; x++) { |
| 499 |
index = y*xsize+x; |
| 500 |
p_red = data.red[index]; |
| 501 |
p_green = data.green[index]; |
| 502 |
p_blue = data.blue[index]; |
| 503 |
if (!palet.length) { |
| 504 |
if (color) |
| 505 |
pixel = (((psiconv_u32) (p_red * (1 << redbits) + 0.5)) |
| 506 |
<< (greenbits+bluebits)) + |
| 507 |
(((psiconv_u32) (p_green * (1 << greenbits) + 0.5)) |
| 508 |
<< bluebits) + |
| 509 |
((psiconv_u32) (p_blue * (1 << bluebits) + 0.5)); |
| 510 |
else |
| 511 |
pixel = (p_red + p_green + p_blue)/3.0 * (1 << colordepth); |
| 512 |
} else { |
| 513 |
dist = 4; /* Max distance is 3, so this is safe */ |
| 514 |
pixel = -1; |
| 515 |
for (i = 0; i < palet.length; i++) { |
| 516 |
new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) + |
| 517 |
(p_green - palet.green[i]) * (p_green - palet.green[i]) + |
| 518 |
(p_blue - palet.blue[i]) * (p_blue - palet.blue[i]); |
| 519 |
if (new_dist < dist) { |
| 520 |
pixel = i; |
| 521 |
dist = new_dist; |
| 522 |
} |
| 523 |
} |
| 524 |
} |
| 525 |
if ((res = psiconv_list_add(*pixels,&pixel))) |
| 526 |
goto ERROR2; |
| 527 |
} |
| 528 |
} |
| 529 |
return 0; |
| 530 |
|
| 531 |
ERROR2: |
| 532 |
psiconv_list_free(*pixels); |
| 533 |
ERROR1: |
| 534 |
return res; |
| 535 |
} |
| 536 |
|
| 537 |
int psiconv_pixel_data_to_bytes(const psiconv_config config, |
| 538 |
psiconv_pixel_bytes *bytes, int xsize, |
| 539 |
int ysize, const psiconv_pixel_ints pixels, |
| 540 |
int colordepth) |
| 541 |
{ |
| 542 |
int res; |
| 543 |
int x,y; |
| 544 |
|
| 545 |
psiconv_u32 inputdata; |
| 546 |
psiconv_u8 outputbyte; |
| 547 |
psiconv_u32 *pixelptr; |
| 548 |
int inputbitsleft,outputbitnr,bitsfit,outputbytenr; |
| 549 |
|
| 550 |
|
| 551 |
if (!bytes) { |
| 552 |
psiconv_warn(config,0,0,"NULL pixel data"); |
| 553 |
res = -PSICONV_E_GENERATE; |
| 554 |
goto ERROR1; |
| 555 |
} |
| 556 |
if (!pixels) { |
| 557 |
psiconv_warn(config,0,0,"NULL pixel data"); |
| 558 |
res = -PSICONV_E_GENERATE; |
| 559 |
goto ERROR1; |
| 560 |
} |
| 561 |
if (psiconv_list_length(pixels) != xsize * ysize) { |
| 562 |
psiconv_warn(config,0,0,"Pixel number is not correct"); |
| 563 |
res = -PSICONV_E_GENERATE; |
| 564 |
goto ERROR1; |
| 565 |
} |
| 566 |
|
| 567 |
if (!(*bytes = psiconv_list_new(sizeof(psiconv_u8)))) { |
| 568 |
res = -PSICONV_E_NOMEM; |
| 569 |
goto ERROR1; |
| 570 |
} |
| 571 |
|
| 572 |
|
| 573 |
outputbitnr = 0; |
| 574 |
outputbyte = 0; |
| 575 |
for (y = 0; y < ysize; y++) { |
| 576 |
outputbytenr = 0; |
| 577 |
for (x = 0; x < xsize; x++) { |
| 578 |
if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) { |
| 579 |
psiconv_warn(config,0,0,"Massive internal corruption"); |
| 580 |
res = -PSICONV_E_NOMEM; |
| 581 |
goto ERROR2; |
| 582 |
} |
| 583 |
inputbitsleft = colordepth; |
| 584 |
inputdata = *pixelptr; |
| 585 |
while (inputbitsleft) { |
| 586 |
bitsfit = (inputbitsleft+outputbitnr<=8?inputbitsleft:8-outputbitnr); |
| 587 |
outputbyte |= (inputdata & ((1 << bitsfit) - 1)) << outputbitnr; |
| 588 |
inputdata = inputdata >> bitsfit; |
| 589 |
inputbitsleft -= bitsfit; |
| 590 |
outputbitnr += bitsfit; |
| 591 |
if (outputbitnr == 8) { |
| 592 |
if ((res = psiconv_list_add(*bytes,&outputbyte))) |
| 593 |
goto ERROR2; |
| 594 |
outputbitnr = 0; |
| 595 |
outputbyte = 0; |
| 596 |
outputbytenr ++; |
| 597 |
} |
| 598 |
} |
| 599 |
} |
| 600 |
/* Always end lines on a long border */ |
| 601 |
if (outputbitnr != 0) { |
| 602 |
if ((res = psiconv_list_add(*bytes,&outputbyte))) |
| 603 |
goto ERROR2; |
| 604 |
outputbitnr = 0; |
| 605 |
outputbyte = 0; |
| 606 |
outputbytenr ++; |
| 607 |
} |
| 608 |
|
| 609 |
while (outputbytenr % 0x04) { |
| 610 |
if ((res = psiconv_list_add(*bytes,&outputbyte))) |
| 611 |
goto ERROR2; |
| 612 |
outputbytenr ++; |
| 613 |
} |
| 614 |
} |
| 615 |
|
| 616 |
return 0; |
| 617 |
|
| 618 |
ERROR2: |
| 619 |
psiconv_list_free(*bytes); |
| 620 |
ERROR1: |
| 621 |
return res; |
| 622 |
} |
| 623 |
|
| 624 |
/* RLE8 encoding: |
| 625 |
Marker bytes followed by one or more data bytes. |
| 626 |
Marker value 0x00-0x7f: repeat the next data byte (marker+1) times |
| 627 |
Marker value 0xff-0x80: (0x100-marker) data bytes follow */ |
| 628 |
int psiconv_encode_rle8(const psiconv_config config, |
| 629 |
const psiconv_pixel_bytes plain_bytes, |
| 630 |
psiconv_pixel_bytes *encoded_bytes) |
| 631 |
{ |
| 632 |
int res,i,j,len; |
| 633 |
psiconv_u8 *entry,*next; |
| 634 |
psiconv_u8 temp; |
| 635 |
|
| 636 |
if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry)))) { |
| 637 |
res = -PSICONV_E_NOMEM; |
| 638 |
goto ERROR1; |
| 639 |
} |
| 640 |
|
| 641 |
for (i = 0; i < psiconv_list_length(plain_bytes);) { |
| 642 |
if (!(entry = psiconv_list_get(plain_bytes,i))) { |
| 643 |
res = -PSICONV_E_NOMEM; |
| 644 |
goto ERROR2; |
| 645 |
} |
| 646 |
if (!(next = psiconv_list_get(plain_bytes,i+1))) { |
| 647 |
res = -PSICONV_E_NOMEM; |
| 648 |
goto ERROR2; |
| 649 |
} |
| 650 |
if (i == psiconv_list_length(plain_bytes) - 2) { |
| 651 |
temp = 0xfe; |
| 652 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 653 |
goto ERROR2; |
| 654 |
if ((res = psiconv_list_add(*encoded_bytes,entry))) |
| 655 |
goto ERROR2; |
| 656 |
if ((res = psiconv_list_add(*encoded_bytes,next))) |
| 657 |
goto ERROR2; |
| 658 |
i +=2; |
| 659 |
} else if (*next == *entry) { |
| 660 |
len = 0; |
| 661 |
while ((*next == *entry) && |
| 662 |
(i+len + 1 < psiconv_list_length(plain_bytes)) && |
| 663 |
len < 0x80) { |
| 664 |
len ++; |
| 665 |
if (!(next = psiconv_list_get(plain_bytes,i+len))) { |
| 666 |
res = -PSICONV_E_NOMEM; |
| 667 |
goto ERROR2; |
| 668 |
} |
| 669 |
} |
| 670 |
temp = len - 1; |
| 671 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 672 |
goto ERROR2; |
| 673 |
if ((res = psiconv_list_add(*encoded_bytes,entry))) |
| 674 |
goto ERROR2; |
| 675 |
i += len; |
| 676 |
} else { |
| 677 |
len = 1; |
| 678 |
while ((*next != *entry) && |
| 679 |
(i+len+1 < psiconv_list_length(plain_bytes)) && |
| 680 |
len < 0x80) { |
| 681 |
len ++; |
| 682 |
entry = next; |
| 683 |
if (!(next = psiconv_list_get(plain_bytes,i+len))) { |
| 684 |
res = -PSICONV_E_NOMEM; |
| 685 |
goto ERROR2; |
| 686 |
} |
| 687 |
} |
| 688 |
len --; |
| 689 |
temp = 0x100 - len; |
| 690 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 691 |
goto ERROR2; |
| 692 |
for (j = 0; j < len; j++) { |
| 693 |
if (!(next = psiconv_list_get(plain_bytes,i+j))) { |
| 694 |
res = -PSICONV_E_NOMEM; |
| 695 |
goto ERROR2; |
| 696 |
} |
| 697 |
if ((res = psiconv_list_add(*encoded_bytes,next))) |
| 698 |
goto ERROR2; |
| 699 |
} |
| 700 |
i += len; |
| 701 |
} |
| 702 |
} |
| 703 |
return 0; |
| 704 |
|
| 705 |
ERROR2: |
| 706 |
psiconv_list_free(*encoded_bytes); |
| 707 |
ERROR1: |
| 708 |
return res; |
| 709 |
} |
| 710 |
|
| 711 |
/* RLE12 encoding: |
| 712 |
Word based. The 12 least significant bits contain the pixel colors. |
| 713 |
the 4 most signigicant bits are the number of repetitions minus 1 */ |
| 714 |
int psiconv_encode_rle12(const psiconv_config config, |
| 715 |
const psiconv_pixel_bytes plain_bytes, |
| 716 |
psiconv_pixel_bytes *encoded_bytes) |
| 717 |
{ |
| 718 |
typedef psiconv_list psiconv_word_data; /* of psiconv_u16 */ |
| 719 |
psiconv_word_data data; |
| 720 |
int res,i,len,location; |
| 721 |
psiconv_u16 *word_entry,*word_next; |
| 722 |
psiconv_u16 word_data; |
| 723 |
psiconv_u8 byte_temp; |
| 724 |
psiconv_u8 *byte_entry; |
| 725 |
|
| 726 |
|
| 727 |
/* First extract the 12-bit values to encode */ |
| 728 |
if (!(data = psiconv_list_new(sizeof(psiconv_u16)))) { |
| 729 |
res = -PSICONV_E_NOMEM; |
| 730 |
goto ERROR1; |
| 731 |
} |
| 732 |
|
| 733 |
for (i = 0; i < psiconv_list_length(plain_bytes); i++) { |
| 734 |
if (!(byte_entry = psiconv_list_get(plain_bytes,i))) { |
| 735 |
res = -PSICONV_E_NOMEM; |
| 736 |
goto ERROR2; |
| 737 |
} |
| 738 |
location = 0; |
| 739 |
if (location == 0) { |
| 740 |
word_data = *byte_entry; |
| 741 |
location ++; |
| 742 |
} else if (location == 1) { |
| 743 |
word_data = (word_data << 4) + (*byte_entry & 0x0f); |
| 744 |
if ((res = psiconv_list_add(data,&word_data))) |
| 745 |
goto ERROR2; |
| 746 |
word_data = *byte_entry >> 4; |
| 747 |
location ++; |
| 748 |
} else { |
| 749 |
word_data = (word_data << 8) + *byte_entry; |
| 750 |
if ((res = psiconv_list_add(data,&word_data))) |
| 751 |
goto ERROR2; |
| 752 |
location = 0; |
| 753 |
} |
| 754 |
} |
| 755 |
|
| 756 |
if (!(*encoded_bytes = psiconv_list_new(sizeof(psiconv_u8)))) { |
| 757 |
res = -PSICONV_E_NOMEM; |
| 758 |
goto ERROR2; |
| 759 |
} |
| 760 |
|
| 761 |
for (i = 0; i < psiconv_list_length(data);) { |
| 762 |
if (!(word_entry = psiconv_list_get(data,i))) { |
| 763 |
res = -PSICONV_E_NOMEM; |
| 764 |
goto ERROR3; |
| 765 |
} |
| 766 |
|
| 767 |
if (!(word_next = psiconv_list_get(data,i+1))) { |
| 768 |
res = -PSICONV_E_NOMEM; |
| 769 |
goto ERROR3; |
| 770 |
} |
| 771 |
|
| 772 |
if (i == psiconv_list_length(data) - 2) { |
| 773 |
byte_temp = *word_entry && 0xff; |
| 774 |
if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) |
| 775 |
goto ERROR3; |
| 776 |
byte_temp = *word_entry >> 8; |
| 777 |
if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) |
| 778 |
goto ERROR3; |
| 779 |
byte_temp = *word_next && 0xff; |
| 780 |
if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) |
| 781 |
goto ERROR3; |
| 782 |
byte_temp = *word_next >> 8; |
| 783 |
if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) |
| 784 |
goto ERROR3; |
| 785 |
i += 2; |
| 786 |
} |
| 787 |
|
| 788 |
len = 0; |
| 789 |
while ((*word_entry == *word_next) && (len < 16) && |
| 790 |
(i+len+1 < psiconv_list_length(data))) { |
| 791 |
len ++; |
| 792 |
if (!(word_next = psiconv_list_get(data,i+len))) { |
| 793 |
res = -PSICONV_E_NOMEM; |
| 794 |
goto ERROR3; |
| 795 |
} |
| 796 |
} |
| 797 |
|
| 798 |
byte_temp = *word_entry && 0xff; |
| 799 |
if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) |
| 800 |
goto ERROR3; |
| 801 |
byte_temp = (*word_entry >> 8) + ((len - 1) << 4); |
| 802 |
if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) |
| 803 |
goto ERROR3; |
| 804 |
i += len; |
| 805 |
} |
| 806 |
return 0; |
| 807 |
|
| 808 |
ERROR3: |
| 809 |
psiconv_list_free(*encoded_bytes); |
| 810 |
ERROR2: |
| 811 |
psiconv_list_free(data); |
| 812 |
ERROR1: |
| 813 |
return res; |
| 814 |
} |
| 815 |
|
| 816 |
/* RLE16 encoding: |
| 817 |
Marker bytes followed by one or more data words. |
| 818 |
Marker value 0x00-0x7f: repeat the next data word (marker+1) times |
| 819 |
Marker value 0xff-0x80: (0x100-marker) data words follow */ |
| 820 |
int psiconv_encode_rle16(const psiconv_config config, |
| 821 |
const psiconv_pixel_bytes plain_bytes, |
| 822 |
psiconv_pixel_bytes *encoded_bytes) |
| 823 |
{ |
| 824 |
int res,i,j,len; |
| 825 |
psiconv_u8 *entry1,*entry2,*next1,*next2; |
| 826 |
psiconv_u8 temp; |
| 827 |
|
| 828 |
if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry1)))) { |
| 829 |
res = -PSICONV_E_NOMEM; |
| 830 |
goto ERROR1; |
| 831 |
} |
| 832 |
|
| 833 |
for (i = 0; i < psiconv_list_length(plain_bytes);) { |
| 834 |
if (!(entry1 = psiconv_list_get(plain_bytes,i))) { |
| 835 |
res = -PSICONV_E_NOMEM; |
| 836 |
goto ERROR2; |
| 837 |
} |
| 838 |
if (!(entry2 = psiconv_list_get(plain_bytes,i+1))) { |
| 839 |
res = -PSICONV_E_NOMEM; |
| 840 |
goto ERROR2; |
| 841 |
} |
| 842 |
if (!(next1 = psiconv_list_get(plain_bytes,i+2))) { |
| 843 |
res = -PSICONV_E_NOMEM; |
| 844 |
goto ERROR2; |
| 845 |
} |
| 846 |
if (!(next2 = psiconv_list_get(plain_bytes,i+3))) { |
| 847 |
res = -PSICONV_E_NOMEM; |
| 848 |
goto ERROR2; |
| 849 |
} |
| 850 |
if (i == psiconv_list_length(plain_bytes) - 4) { |
| 851 |
temp = 0xfe; |
| 852 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 853 |
goto ERROR2; |
| 854 |
if ((res = psiconv_list_add(*encoded_bytes,entry1))) |
| 855 |
goto ERROR2; |
| 856 |
if ((res = psiconv_list_add(*encoded_bytes,entry2))) |
| 857 |
goto ERROR2; |
| 858 |
if ((res = psiconv_list_add(*encoded_bytes,next1))) |
| 859 |
goto ERROR2; |
| 860 |
if ((res = psiconv_list_add(*encoded_bytes,next2))) |
| 861 |
goto ERROR2; |
| 862 |
i +=4; |
| 863 |
} else if ((*next1 == *entry1) && (*next2 == *entry2)) { |
| 864 |
len = 0; |
| 865 |
while (((*next1 == *entry1) && (*next2 == *entry2)) && |
| 866 |
(i+2*len + 4 < psiconv_list_length(plain_bytes)) && |
| 867 |
len < 0x80) { |
| 868 |
len ++; |
| 869 |
if (!(next1 = psiconv_list_get(plain_bytes,i+len*2))) { |
| 870 |
res = -PSICONV_E_NOMEM; |
| 871 |
goto ERROR2; |
| 872 |
} |
| 873 |
if (!(next2 = psiconv_list_get(plain_bytes,i+len*2+1))) { |
| 874 |
res = -PSICONV_E_NOMEM; |
| 875 |
goto ERROR2; |
| 876 |
} |
| 877 |
} |
| 878 |
temp = len - 1; |
| 879 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 880 |
goto ERROR2; |
| 881 |
if ((res = psiconv_list_add(*encoded_bytes,entry1))) |
| 882 |
goto ERROR2; |
| 883 |
if ((res = psiconv_list_add(*encoded_bytes,entry2))) |
| 884 |
goto ERROR2; |
| 885 |
i += len*2; |
| 886 |
} else { |
| 887 |
len = 1; |
| 888 |
while (((*next1 != *entry1) || (*next2 != *entry2))&& |
| 889 |
(i+len*2+4 < psiconv_list_length(plain_bytes)) && |
| 890 |
len < 0x80) { |
| 891 |
len ++; |
| 892 |
entry1 = next1; |
| 893 |
entry2 = next2; |
| 894 |
if (!(next1 = psiconv_list_get(plain_bytes,i+len*2))) { |
| 895 |
res = -PSICONV_E_NOMEM; |
| 896 |
goto ERROR2; |
| 897 |
} |
| 898 |
if (!(next2 = psiconv_list_get(plain_bytes,i+len*2+1))) { |
| 899 |
res = -PSICONV_E_NOMEM; |
| 900 |
goto ERROR2; |
| 901 |
} |
| 902 |
} |
| 903 |
len --; |
| 904 |
temp = 0x100 - len; |
| 905 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 906 |
goto ERROR2; |
| 907 |
for (j = 0; j < len; j++) { |
| 908 |
if (!(next1 = psiconv_list_get(plain_bytes,i+j*2))) { |
| 909 |
res = -PSICONV_E_NOMEM; |
| 910 |
goto ERROR2; |
| 911 |
} |
| 912 |
if (!(next2 = psiconv_list_get(plain_bytes,i+j*2+1))) { |
| 913 |
res = -PSICONV_E_NOMEM; |
| 914 |
goto ERROR2; |
| 915 |
} |
| 916 |
if ((res = psiconv_list_add(*encoded_bytes,next1))) |
| 917 |
goto ERROR2; |
| 918 |
if ((res = psiconv_list_add(*encoded_bytes,next2))) |
| 919 |
goto ERROR2; |
| 920 |
} |
| 921 |
i += len*2; |
| 922 |
} |
| 923 |
} |
| 924 |
return 0; |
| 925 |
|
| 926 |
ERROR2: |
| 927 |
psiconv_list_free(*encoded_bytes); |
| 928 |
ERROR1: |
| 929 |
return res; |
| 930 |
} |
| 931 |
|
| 932 |
/* RLE24 encoding: |
| 933 |
Marker bytes followed by one or more data byte-triplets. |
| 934 |
Marker value 0x00-0x7f: repeat the next data byte-triplets (marker+1) times |
| 935 |
Marker value 0xff-0x80: (0x100-marker) data byte-triplets follow */ |
| 936 |
int psiconv_encode_rle24(const psiconv_config config, |
| 937 |
const psiconv_pixel_bytes plain_bytes, |
| 938 |
psiconv_pixel_bytes *encoded_bytes) |
| 939 |
{ |
| 940 |
int res,i,j,len; |
| 941 |
psiconv_u8 *entry1,*entry2,*entry3,*next1,*next2,*next3; |
| 942 |
psiconv_u8 temp; |
| 943 |
|
| 944 |
if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry1)))) { |
| 945 |
res = -PSICONV_E_NOMEM; |
| 946 |
goto ERROR1; |
| 947 |
} |
| 948 |
|
| 949 |
for (i = 0; i < psiconv_list_length(plain_bytes);) { |
| 950 |
if (!(entry1 = psiconv_list_get(plain_bytes,i))) { |
| 951 |
res = -PSICONV_E_NOMEM; |
| 952 |
goto ERROR2; |
| 953 |
} |
| 954 |
if (!(entry2 = psiconv_list_get(plain_bytes,i+1))) { |
| 955 |
res = -PSICONV_E_NOMEM; |
| 956 |
goto ERROR2; |
| 957 |
} |
| 958 |
if (!(entry3 = psiconv_list_get(plain_bytes,i+2))) { |
| 959 |
res = -PSICONV_E_NOMEM; |
| 960 |
goto ERROR2; |
| 961 |
} |
| 962 |
if (!(next1 = psiconv_list_get(plain_bytes,i+3))) { |
| 963 |
res = -PSICONV_E_NOMEM; |
| 964 |
goto ERROR2; |
| 965 |
} |
| 966 |
if (!(next2 = psiconv_list_get(plain_bytes,i+4))) { |
| 967 |
res = -PSICONV_E_NOMEM; |
| 968 |
goto ERROR2; |
| 969 |
} |
| 970 |
if (!(next3 = psiconv_list_get(plain_bytes,i+5))) { |
| 971 |
res = -PSICONV_E_NOMEM; |
| 972 |
goto ERROR2; |
| 973 |
} |
| 974 |
if (i == psiconv_list_length(plain_bytes) - 6) { |
| 975 |
temp = 0xfe; |
| 976 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 977 |
goto ERROR2; |
| 978 |
if ((res = psiconv_list_add(*encoded_bytes,entry1))) |
| 979 |
goto ERROR2; |
| 980 |
if ((res = psiconv_list_add(*encoded_bytes,entry2))) |
| 981 |
goto ERROR2; |
| 982 |
if ((res = psiconv_list_add(*encoded_bytes,entry3))) |
| 983 |
goto ERROR2; |
| 984 |
if ((res = psiconv_list_add(*encoded_bytes,next1))) |
| 985 |
goto ERROR2; |
| 986 |
if ((res = psiconv_list_add(*encoded_bytes,next2))) |
| 987 |
goto ERROR2; |
| 988 |
if ((res = psiconv_list_add(*encoded_bytes,next3))) |
| 989 |
goto ERROR2; |
| 990 |
i +=4; |
| 991 |
} else if ((*next1 == *entry1) && (*next2 == *entry2) && |
| 992 |
(*next3 == *entry3)) { |
| 993 |
len = 0; |
| 994 |
while (((*next1 == *entry1) && (*next2 == *entry2) && |
| 995 |
(*next3 == *entry3)) && |
| 996 |
(i+3*len + 6 < psiconv_list_length(plain_bytes)) && |
| 997 |
len < 0x80) { |
| 998 |
len ++; |
| 999 |
if (!(next1 = psiconv_list_get(plain_bytes,i+len*3))) { |
| 1000 |
res = -PSICONV_E_NOMEM; |
| 1001 |
goto ERROR2; |
| 1002 |
} |
| 1003 |
if (!(next2 = psiconv_list_get(plain_bytes,i+len*3+1))) { |
| 1004 |
res = -PSICONV_E_NOMEM; |
| 1005 |
goto ERROR2; |
| 1006 |
} |
| 1007 |
if (!(next3 = psiconv_list_get(plain_bytes,i+len*3+2))) { |
| 1008 |
res = -PSICONV_E_NOMEM; |
| 1009 |
goto ERROR2; |
| 1010 |
} |
| 1011 |
} |
| 1012 |
temp = len - 1; |
| 1013 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 1014 |
goto ERROR2; |
| 1015 |
if ((res = psiconv_list_add(*encoded_bytes,entry1))) |
| 1016 |
goto ERROR2; |
| 1017 |
if ((res = psiconv_list_add(*encoded_bytes,entry2))) |
| 1018 |
goto ERROR2; |
| 1019 |
if ((res = psiconv_list_add(*encoded_bytes,entry3))) |
| 1020 |
goto ERROR2; |
| 1021 |
i += len*3; |
| 1022 |
} else { |
| 1023 |
len = 1; |
| 1024 |
while (((*next1 != *entry1) || (*next2 != *entry2) || |
| 1025 |
(*next3 != *entry3)) && |
| 1026 |
(i+len*3+6 < psiconv_list_length(plain_bytes)) && |
| 1027 |
len < 0x80) { |
| 1028 |
len ++; |
| 1029 |
entry1 = next1; |
| 1030 |
entry2 = next2; |
| 1031 |
entry3 = next3; |
| 1032 |
if (!(next1 = psiconv_list_get(plain_bytes,i+len*3))) { |
| 1033 |
res = -PSICONV_E_NOMEM; |
| 1034 |
goto ERROR2; |
| 1035 |
} |
| 1036 |
if (!(next2 = psiconv_list_get(plain_bytes,i+len*3+1))) { |
| 1037 |
res = -PSICONV_E_NOMEM; |
| 1038 |
goto ERROR2; |
| 1039 |
} |
| 1040 |
if (!(next3 = psiconv_list_get(plain_bytes,i+len*3+2))) { |
| 1041 |
res = -PSICONV_E_NOMEM; |
| 1042 |
goto ERROR2; |
| 1043 |
} |
| 1044 |
} |
| 1045 |
len --; |
| 1046 |
temp = 0x100 - len; |
| 1047 |
if ((res = psiconv_list_add(*encoded_bytes,&temp))) |
| 1048 |
goto ERROR2; |
| 1049 |
for (j = 0; j < len; j++) { |
| 1050 |
if (!(next1 = psiconv_list_get(plain_bytes,i+j*3))) { |
| 1051 |
res = -PSICONV_E_NOMEM; |
| 1052 |
goto ERROR2; |
| 1053 |
} |
| 1054 |
if (!(next2 = psiconv_list_get(plain_bytes,i+j*3+1))) { |
| 1055 |
res = -PSICONV_E_NOMEM; |
| 1056 |
goto ERROR2; |
| 1057 |
} |
| 1058 |
if (!(next2 = psiconv_list_get(plain_bytes,i+j*3+2))) { |
| 1059 |
res = -PSICONV_E_NOMEM; |
| 1060 |
goto ERROR2; |
| 1061 |
} |
| 1062 |
if ((res = psiconv_list_add(*encoded_bytes,next1))) |
| 1063 |
goto ERROR2; |
| 1064 |
if ((res = psiconv_list_add(*encoded_bytes,next2))) |
| 1065 |
goto ERROR2; |
| 1066 |
if ((res = psiconv_list_add(*encoded_bytes,next3))) |
| 1067 |
goto ERROR2; |
| 1068 |
} |
| 1069 |
i += len*3; |
| 1070 |
} |
| 1071 |
} |
| 1072 |
return 0; |
| 1073 |
|
| 1074 |
ERROR2: |
| 1075 |
psiconv_list_free(*encoded_bytes); |
| 1076 |
ERROR1: |
| 1077 |
return res; |
| 1078 |
} |
| 1079 |
|
| 1080 |
|
| 1081 |
int psiconv_write_sketch_section(const psiconv_config config, |
| 1082 |
psiconv_buffer buf, |
| 1083 |
const psiconv_sketch_section value) |
| 1084 |
{ |
| 1085 |
int res; |
| 1086 |
|
| 1087 |
if (!value) { |
| 1088 |
psiconv_warn(config,0,0,"NULL sketch section"); |
| 1089 |
res = -PSICONV_E_GENERATE; |
| 1090 |
goto ERROR1; |
| 1091 |
} |
| 1092 |
|
| 1093 |
if ((res = psiconv_write_u16(config,buf,value->displayed_xsize))) |
| 1094 |
goto ERROR1; |
| 1095 |
if ((res = psiconv_write_u16(config,buf,value->displayed_ysize))) |
| 1096 |
goto ERROR1; |
| 1097 |
if ((res = psiconv_write_u16(config,buf,value->picture_data_x_offset))) |
| 1098 |
goto ERROR1; |
| 1099 |
if ((res = psiconv_write_u16(config,buf,value->picture_data_y_offset))) |
| 1100 |
goto ERROR1; |
| 1101 |
if ((res = psiconv_write_u16(config,buf,value->displayed_size_x_offset))) |
| 1102 |
goto ERROR1; |
| 1103 |
if ((res = psiconv_write_u16(config,buf,value->displayed_size_y_offset))) |
| 1104 |
goto ERROR1; |
| 1105 |
if ((res = psiconv_write_u16(config,buf,value->form_xsize))) |
| 1106 |
goto ERROR1; |
| 1107 |
if ((res = psiconv_write_u16(config,buf,value->form_ysize))) |
| 1108 |
goto ERROR1; |
| 1109 |
if ((res = psiconv_write_u16(config,buf,0x0000))) |
| 1110 |
goto ERROR1; |
| 1111 |
if ((res = psiconv_write_paint_data_section(config,buf,value->picture,0))) |
| 1112 |
goto ERROR1; |
| 1113 |
if ((res = psiconv_write_u16(config,buf,value->magnification_x * 0x03e8))) |
| 1114 |
goto ERROR1; |
| 1115 |
if ((res = psiconv_write_u16(config,buf,value->magnification_y * 0x03e8))) |
| 1116 |
goto ERROR1; |
| 1117 |
if ((res = psiconv_write_u32(config,buf,value->cut_left * 0x0c * |
| 1118 |
value->displayed_xsize))) |
| 1119 |
goto ERROR1; |
| 1120 |
if ((res = psiconv_write_u32(config,buf,value->cut_right * 0x0c * |
| 1121 |
value->displayed_xsize))) |
| 1122 |
goto ERROR1; |
| 1123 |
if ((res = psiconv_write_u32(config,buf,value->cut_top * 0x0c * |
| 1124 |
value->displayed_ysize))) |
| 1125 |
goto ERROR1; |
| 1126 |
if ((res = psiconv_write_u32(config,buf,value->cut_bottom * 0x0c * |
| 1127 |
value->displayed_ysize))) |
| 1128 |
goto ERROR1; |
| 1129 |
|
| 1130 |
ERROR1: |
| 1131 |
return res; |
| 1132 |
} |
| 1133 |
|
| 1134 |
int psiconv_write_clipart_section(const psiconv_config config, |
| 1135 |
psiconv_buffer buf, |
| 1136 |
const psiconv_clipart_section value) |
| 1137 |
{ |
| 1138 |
int res; |
| 1139 |
|
| 1140 |
|
| 1141 |
if (!value) { |
| 1142 |
psiconv_warn(config,0,psiconv_buffer_length(buf), |
| 1143 |
"NULL Clipart Section"); |
| 1144 |
res = -PSICONV_E_GENERATE; |
| 1145 |
goto ERROR; |
| 1146 |
} |
| 1147 |
if ((res = psiconv_write_u32(config,buf,PSICONV_ID_CLIPART_ITEM))) |
| 1148 |
goto ERROR; |
| 1149 |
if ((res = psiconv_write_u32(config,buf,0x00000002))) |
| 1150 |
goto ERROR; |
| 1151 |
if ((res = psiconv_write_u32(config,buf,0x00000000))) |
| 1152 |
goto ERROR; |
| 1153 |
if ((res = psiconv_write_u32(config,buf,0x00000000))) |
| 1154 |
goto ERROR; |
| 1155 |
if ((res = psiconv_write_u32(config,buf,0x0000000C))) |
| 1156 |
goto ERROR; |
| 1157 |
if ((res = psiconv_write_paint_data_section(config,buf,value->picture,1))) |
| 1158 |
goto ERROR; |
| 1159 |
|
| 1160 |
ERROR: |
| 1161 |
return res; |
| 1162 |
} |
| 1163 |
|
| 1164 |
int psiconv_write_jumptable_section(const psiconv_config config, |
| 1165 |
psiconv_buffer buf, |
| 1166 |
const psiconv_jumptable_section value) |
| 1167 |
{ |
| 1168 |
int res,i; |
| 1169 |
psiconv_u32 *offset_ptr; |
| 1170 |
|
| 1171 |
|
| 1172 |
if (!value) { |
| 1173 |
psiconv_warn(config,0,psiconv_buffer_length(buf), |
| 1174 |
"NULL Jumptable Section"); |
| 1175 |
res = -PSICONV_E_GENERATE; |
| 1176 |
goto ERROR; |
| 1177 |
} |
| 1178 |
if ((res = psiconv_write_u32(config,buf,psiconv_list_length(value)))) |
| 1179 |
goto ERROR; |
| 1180 |
for (i = 0; i < psiconv_list_length(value); i++) { |
| 1181 |
if (!(offset_ptr = psiconv_list_get(value,i))) { |
| 1182 |
psiconv_warn(config,0,psiconv_buffer_length(buf), |
| 1183 |
"Massive memory corruption"); |
| 1184 |
res = -PSICONV_E_NOMEM; |
| 1185 |
goto ERROR; |
| 1186 |
} |
| 1187 |
if ((res = psiconv_write_offset(config,buf,*offset_ptr))) |
| 1188 |
goto ERROR; |
| 1189 |
} |
| 1190 |
|
| 1191 |
ERROR: |
| 1192 |
return res; |
| 1193 |
} |
| 1194 |
|