summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/Palm2QImage.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/Palm2QImage.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/Palm2QImage.cpp290
1 files changed, 290 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/Palm2QImage.cpp b/noncore/apps/opie-reader/Palm2QImage.cpp
new file mode 100644
index 0000000..ef88cc5
--- a/dev/null
+++ b/noncore/apps/opie-reader/Palm2QImage.cpp
@@ -0,0 +1,290 @@
1/* -*- mode: c; indent-tabs-mode: nil; -*- */
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <unistd.h> /* for link */
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <stdarg.h>
9
10#include <qimage.h>
11
12/***********************************************************************/
13/***********************************************************************/
14/***** *****/
15/***** Code to decode the Palm image format to JPEG *****/
16/***** *****/
17/***********************************************************************/
18/***********************************************************************/
19
20#define READ_BIGENDIAN_SHORT(p) (((p)[0] << 8)|((p)[1]))
21#define READ_BIGENDIAN_LONG(p) (((p)[0] << 24)|((p)[1] << 16)|((p)[2] << 8)|((p)[3]))
22
23#define PALM_IS_COMPRESSED_FLAG 0x8000
24#define PALM_HAS_COLORMAP_FLAG 0x4000
25#define PALM_HAS_TRANSPARENCY_FLAG 0x2000
26#define PALM_DIRECT_COLOR_FLAG 0x0400
27#define PALM_4_BYTE_FIELD_FLAG 0x0200
28
29#define PALM_COMPRESSION_SCANLINE 0x00
30#define PALM_COMPRESSION_RLE 0x01
31#define PALM_COMPRESSION_PACKBITS 0x02
32#define PALM_COMPRESSION_NONE 0xFF
33
34#define PALM_COLORMAP_SIZE 232
35
36typedef struct {
37 unsigned char red;
38 unsigned char green;
39 unsigned char blue;
40} ColorMapEntry;
41
42static ColorMapEntry Palm8BitColormap[] = {
43 { 255, 255, 255 }, { 255, 204, 255 }, { 255, 153, 255 }, { 255, 102, 255 },
44 { 255, 51, 255 }, { 255, 0, 255 }, { 255, 255, 204 }, { 255, 204, 204 },
45 { 255, 153, 204 }, { 255, 102, 204 }, { 255, 51, 204 }, { 255, 0, 204 },
46 { 255, 255, 153 }, { 255, 204, 153 }, { 255, 153, 153 }, { 255, 102, 153 },
47 { 255, 51, 153 }, { 255, 0, 153 }, { 204, 255, 255 }, { 204, 204, 255 },
48 { 204, 153, 255 }, { 204, 102, 255 }, { 204, 51, 255 }, { 204, 0, 255 },
49 { 204, 255, 204 }, { 204, 204, 204 }, { 204, 153, 204 }, { 204, 102, 204 },
50 { 204, 51, 204 }, { 204, 0, 204 }, { 204, 255, 153 }, { 204, 204, 153 },
51 { 204, 153, 153 }, { 204, 102, 153 }, { 204, 51, 153 }, { 204, 0, 153 },
52 { 153, 255, 255 }, { 153, 204, 255 }, { 153, 153, 255 }, { 153, 102, 255 },
53 { 153, 51, 255 }, { 153, 0, 255 }, { 153, 255, 204 }, { 153, 204, 204 },
54 { 153, 153, 204 }, { 153, 102, 204 }, { 153, 51, 204 }, { 153, 0, 204 },
55 { 153, 255, 153 }, { 153, 204, 153 }, { 153, 153, 153 }, { 153, 102, 153 },
56 { 153, 51, 153 }, { 153, 0, 153 }, { 102, 255, 255 }, { 102, 204, 255 },
57 { 102, 153, 255 }, { 102, 102, 255 }, { 102, 51, 255 }, { 102, 0, 255 },
58 { 102, 255, 204 }, { 102, 204, 204 }, { 102, 153, 204 }, { 102, 102, 204 },
59 { 102, 51, 204 }, { 102, 0, 204 }, { 102, 255, 153 }, { 102, 204, 153 },
60 { 102, 153, 153 }, { 102, 102, 153 }, { 102, 51, 153 }, { 102, 0, 153 },
61 { 51, 255, 255 }, { 51, 204, 255 }, { 51, 153, 255 }, { 51, 102, 255 },
62 { 51, 51, 255 }, { 51, 0, 255 }, { 51, 255, 204 }, { 51, 204, 204 },
63 { 51, 153, 204 }, { 51, 102, 204 }, { 51, 51, 204 }, { 51, 0, 204 },
64 { 51, 255, 153 }, { 51, 204, 153 }, { 51, 153, 153 }, { 51, 102, 153 },
65 { 51, 51, 153 }, { 51, 0, 153 }, { 0, 255, 255 }, { 0, 204, 255 },
66 { 0, 153, 255 }, { 0, 102, 255 }, { 0, 51, 255 }, { 0, 0, 255 },
67 { 0, 255, 204 }, { 0, 204, 204 }, { 0, 153, 204 }, { 0, 102, 204 },
68 { 0, 51, 204 }, { 0, 0, 204 }, { 0, 255, 153 }, { 0, 204, 153 },
69 { 0, 153, 153 }, { 0, 102, 153 }, { 0, 51, 153 }, { 0, 0, 153 },
70 { 255, 255, 102 }, { 255, 204, 102 }, { 255, 153, 102 }, { 255, 102, 102 },
71 { 255, 51, 102 }, { 255, 0, 102 }, { 255, 255, 51 }, { 255, 204, 51 },
72 { 255, 153, 51 }, { 255, 102, 51 }, { 255, 51, 51 }, { 255, 0, 51 },
73 { 255, 255, 0 }, { 255, 204, 0 }, { 255, 153, 0 }, { 255, 102, 0 },
74 { 255, 51, 0 }, { 255, 0, 0 }, { 204, 255, 102 }, { 204, 204, 102 },
75 { 204, 153, 102 }, { 204, 102, 102 }, { 204, 51, 102 }, { 204, 0, 102 },
76 { 204, 255, 51 }, { 204, 204, 51 }, { 204, 153, 51 }, { 204, 102, 51 },
77 { 204, 51, 51 }, { 204, 0, 51 }, { 204, 255, 0 }, { 204, 204, 0 },
78 { 204, 153, 0 }, { 204, 102, 0 }, { 204, 51, 0 }, { 204, 0, 0 },
79 { 153, 255, 102 }, { 153, 204, 102 }, { 153, 153, 102 }, { 153, 102, 102 },
80 { 153, 51, 102 }, { 153, 0, 102 }, { 153, 255, 51 }, { 153, 204, 51 },
81 { 153, 153, 51 }, { 153, 102, 51 }, { 153, 51, 51 }, { 153, 0, 51 },
82 { 153, 255, 0 }, { 153, 204, 0 }, { 153, 153, 0 }, { 153, 102, 0 },
83 { 153, 51, 0 }, { 153, 0, 0 }, { 102, 255, 102 }, { 102, 204, 102 },
84 { 102, 153, 102 }, { 102, 102, 102 }, { 102, 51, 102 }, { 102, 0, 102 },
85 { 102, 255, 51 }, { 102, 204, 51 }, { 102, 153, 51 }, { 102, 102, 51 },
86 { 102, 51, 51 }, { 102, 0, 51 }, { 102, 255, 0 }, { 102, 204, 0 },
87 { 102, 153, 0 }, { 102, 102, 0 }, { 102, 51, 0 }, { 102, 0, 0 },
88 { 51, 255, 102 }, { 51, 204, 102 }, { 51, 153, 102 }, { 51, 102, 102 },
89 { 51, 51, 102 }, { 51, 0, 102 }, { 51, 255, 51 }, { 51, 204, 51 },
90 { 51, 153, 51 }, { 51, 102, 51 }, { 51, 51, 51 }, { 51, 0, 51 },
91 { 51, 255, 0 }, { 51, 204, 0 }, { 51, 153, 0 }, { 51, 102, 0 },
92 { 51, 51, 0 }, { 51, 0, 0 }, { 0, 255, 102 }, { 0, 204, 102 },
93 { 0, 153, 102 }, { 0, 102, 102 }, { 0, 51, 102 }, { 0, 0, 102 },
94 { 0, 255, 51 }, { 0, 204, 51 }, { 0, 153, 51 }, { 0, 102, 51 },
95 { 0, 51, 51 }, { 0, 0, 51 }, { 0, 255, 0 }, { 0, 204, 0 },
96 { 0, 153, 0 }, { 0, 102, 0 }, { 0, 51, 0 }, { 17, 17, 17 },
97 { 34, 34, 34 }, { 68, 68, 68 }, { 85, 85, 85 }, { 119, 119, 119 },
98 { 136, 136, 136 }, { 170, 170, 170 }, { 187, 187, 187 }, { 221, 221, 221 },
99 { 238, 238, 238 }, { 192, 192, 192 }, { 128, 0, 0 }, { 128, 0, 128 },
100 { 0, 128, 0 }, { 0, 128, 128 }, { 0, 0, 0 }, { 0, 0, 0 },
101 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
102 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
103 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
104 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
105 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
106 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }};
107
108static ColorMapEntry Palm1BitColormap[] = {{ 255, 255, 255 }, { 0, 0, 0 }};
109
110static ColorMapEntry Palm2BitColormap[] = {
111 { 255, 255, 255 }, { 192, 192, 192 }, { 128, 128, 128 }, { 0, 0, 0 }};
112
113static ColorMapEntry Palm4BitColormap[] = {
114 { 255, 255, 255 }, { 238, 238, 238 }, { 221, 221, 221 }, { 204, 204, 204 },
115 { 187, 187, 187 }, { 170, 170, 170 }, { 153, 153, 153 }, { 136, 136, 136 },
116 { 119, 119, 119 }, { 102, 102, 102 }, { 85, 85, 85 }, { 68, 68, 68 },
117 { 51, 51, 51 }, { 34, 34, 34 }, { 17, 17, 17 }, { 0, 0, 0 }};
118
119QImage* Palm2QImage
120 (unsigned char *image_bytes_in, int byte_count_in)
121{
122 unsigned int width, height, bytes_per_row, flags, next_depth_offset;
123 unsigned int bits_per_pixel, version, transparent_index, compression_type, i, j, inval, inbit, mask, incount;
124 unsigned int palm_red_bits, palm_green_bits, palm_blue_bits;
125 unsigned char *palm_ptr, *x_ptr, *imagedata, *inbyte, *rowbuf, *lastrow,
126 *imagedatastart, *palmimage;
127 ColorMapEntry *colormap;
128
129 palmimage = image_bytes_in;
130 width = READ_BIGENDIAN_SHORT(palmimage + 0);
131 height = READ_BIGENDIAN_SHORT(palmimage + 2);
132 bytes_per_row = READ_BIGENDIAN_SHORT(palmimage + 4);
133 flags = READ_BIGENDIAN_SHORT(palmimage + 6);
134 bits_per_pixel = palmimage[8];
135 version = palmimage[9];
136 next_depth_offset = READ_BIGENDIAN_SHORT(palmimage + 10);
137 transparent_index = palmimage[12];
138 compression_type = palmimage[13];
139 /* bytes 14 and 15 are reserved by Palm and always 0 */
140
141#if 0
142 qDebug ("Palm image is %dx%d, %d bpp, version %d, flags 0x%x, compression %d",
143 width, height, bits_per_pixel, version, flags, compression_type);
144#endif
145
146 if (compression_type == PALM_COMPRESSION_PACKBITS) {
147 qDebug ("Image uses packbits compression; not yet supported");
148 return NULL;
149 } else if ((compression_type != PALM_COMPRESSION_NONE) &&
150 (compression_type != PALM_COMPRESSION_RLE) &&
151 (compression_type != PALM_COMPRESSION_SCANLINE)) {
152 qDebug ("Image uses unknown compression, code 0x%x", compression_type);
153 return NULL;
154 }
155
156 /* as of PalmOS 4.0, there are 6 different kinds of Palm pixmaps:
157
158 1, 2, or 4 bit grayscale
159 8-bit StaticColor using the Palm standard colormap
160 8-bit PseudoColor using a user-specified colormap
161 16-bit DirectColor using 5 bits for red, 6 for green, and 5 for blue
162
163 Each of these can be compressed with one of four compression schemes,
164 "RLE", "Scanline", "PackBits", or none.
165
166 We begin by constructing the colormap.
167 */
168
169 if (flags & PALM_HAS_COLORMAP_FLAG) {
170 qDebug("Palm images with custom colormaps are not currently supported.\n");
171 return NULL;
172 } else if (bits_per_pixel == 1) {
173 colormap = Palm1BitColormap;
174 imagedatastart = palmimage + 16;
175 } else if (bits_per_pixel == 2) {
176 colormap = Palm2BitColormap;
177 imagedatastart = palmimage + 16;
178 } else if (bits_per_pixel == 4) {
179 colormap = Palm4BitColormap;
180 imagedatastart = palmimage + 16;
181 } else if (bits_per_pixel == 8) {
182 colormap = Palm8BitColormap;
183 imagedatastart = palmimage + 16;
184 } else if (bits_per_pixel == 16 && (flags & PALM_DIRECT_COLOR_FLAG)) {
185 colormap = NULL;
186 palm_red_bits = palmimage[16];
187 palm_green_bits = palmimage[17];
188 palm_blue_bits = palmimage[18];
189 if (palm_blue_bits > 8 || palm_green_bits > 8 || palm_red_bits > 8) {
190 qDebug("Can't handle this format DirectColor image -- too wide in some color (%d:%d:%d)\n",
191 palm_red_bits, palm_green_bits, palm_blue_bits);
192 return NULL;
193 }
194 if (bits_per_pixel > (8 * sizeof(unsigned long))) {
195 qDebug ("Can't handle this format DirectColor image -- too many bits per pixel (%d)\n",
196 bits_per_pixel);
197 return NULL;
198 }
199 imagedatastart = palmimage + 24;
200 } else {
201 qDebug("Unknown bits-per-pixel of %d encountered.\n", bits_per_pixel);
202 return NULL;
203 }
204
205 QImage* qimage = new QImage(width, height, 16);
206
207 /* row by row, uncompress the Palm image and copy it to the JPEG buffer */
208 rowbuf = new unsigned char[bytes_per_row * width];
209 lastrow = new unsigned char[bytes_per_row * width];
210
211 for (i=0, palm_ptr = imagedatastart , x_ptr = imagedata; i < height; ++i) {
212
213 /* first, uncompress the Palm image */
214 if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_RLE)) {
215 for (j = 0; j < bytes_per_row; ) {
216 incount = *palm_ptr++;
217 inval = *palm_ptr++;
218 memset(rowbuf + j, inval, incount);
219 j += incount;
220 }
221 } else if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_SCANLINE)) {
222 for (j = 0; j < bytes_per_row; j += 8) {
223 incount = *palm_ptr++;
224 inval = ((bytes_per_row - j) < 8) ? (bytes_per_row - j) : 8;
225 for (inbit = 0; inbit < inval; inbit += 1) {
226 if (incount & (1 << (7 - inbit)))
227 rowbuf[j + inbit] = *palm_ptr++;
228 else
229 rowbuf[j + inbit] = lastrow[j + inbit];
230 }
231 }
232 memcpy (lastrow, rowbuf, bytes_per_row);
233 } else if (((flags & PALM_IS_COMPRESSED_FLAG) &&
234 (compression_type == PALM_COMPRESSION_NONE)) ||
235 (flags && PALM_IS_COMPRESSED_FLAG) == 0) {
236 memcpy (rowbuf, palm_ptr, bytes_per_row);
237 palm_ptr += bytes_per_row;
238 }
239
240 /* next, write it to the GDK bitmap */
241 if (colormap) {
242 mask = (1 << bits_per_pixel) - 1;
243 for (inbit = 8 - bits_per_pixel, inbyte = rowbuf, j = 0; j < width; ++j) {
244 inval = ((*inbyte) & (mask << inbit)) >> inbit;
245 /* correct for oddity of the 8-bit color Palm pixmap... */
246 if ((bits_per_pixel == 8) && (inval == 0xFF)) inval = 231;
247 /* now lookup the correct color and set the pixel in the GTK bitmap */
248 QRgb colour = qRgb(colormap[inval].red, colormap[inval].green, colormap[inval].blue);
249 qimage->setPixel(j, i, colour);
250 if (!inbit) {
251 ++inbyte;
252 inbit = 8 - bits_per_pixel;
253 } else {
254 inbit -= bits_per_pixel;
255 }
256 }
257 } else if (!colormap &&
258 bits_per_pixel == 16) {
259 for (inbyte = rowbuf, j = 0; j < width; ++j) {
260 inval = (inbyte[0] << 8) | inbyte[1];
261#if 0
262 qDebug ("pixel is %d,%d (%02x:%02x:%02x)",
263 j, i,
264 (inval >> (bits_per_pixel - palm_red_bits)) & ((1 << palm_red_bits) - 1),
265 (inval >> palm_blue_bits) & ((1 << palm_green_bits) - 1),
266 (inval >> 0) & ((1 << palm_blue_bits) - 1));
267#endif
268 QRgb colour = qRgb(
269 (inval >> (bits_per_pixel - palm_red_bits)) & ((1 << palm_red_bits) - 1),
270 (inval >> palm_blue_bits) & ((1 << palm_green_bits) - 1),
271 (inval >> 0) & ((1 << palm_blue_bits) - 1));
272 qimage->setPixel(j, i, colour);
273 inbyte += 2;
274 }
275 }
276 }
277
278 delete [] rowbuf;
279 delete [] lastrow;
280
281 return qimage;
282}
283
284QPixmap* hRule(int w, int h, unsigned char r, unsigned char g, unsigned char b)
285{
286// qDebug("hrule [%d, %d]", w, h);
287 QPixmap* qimage = new QPixmap(w, h);
288 qimage->fill(QColor(r,g,b));
289 return qimage;
290}