00001
00002
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #ifndef _WINDOWS
00007 #include <unistd.h>
00008 #endif
00009 #include <sys/types.h>
00010 #include <sys/stat.h>
00011 #include <stdarg.h>
00012
00013 #include <qimage.h>
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define READ_BIGENDIAN_SHORT(p) (((p)[0] << 8)|((p)[1]))
00024 #define READ_BIGENDIAN_LONG(p) (((p)[0] << 24)|((p)[1] << 16)|((p)[2] << 8)|((p)[3]))
00025
00026 #define PALM_IS_COMPRESSED_FLAG 0x8000
00027 #define PALM_HAS_COLORMAP_FLAG 0x4000
00028 #define PALM_HAS_TRANSPARENCY_FLAG 0x2000
00029 #define PALM_DIRECT_COLOR_FLAG 0x0400
00030 #define PALM_4_BYTE_FIELD_FLAG 0x0200
00031
00032 #define PALM_COMPRESSION_SCANLINE 0x00
00033 #define PALM_COMPRESSION_RLE 0x01
00034 #define PALM_COMPRESSION_PACKBITS 0x02
00035 #define PALM_COMPRESSION_NONE 0xFF
00036
00037 #define PALM_COLORMAP_SIZE 232
00038
00039 typedef struct {
00040 unsigned char red;
00041 unsigned char green;
00042 unsigned char blue;
00043 } ColorMapEntry;
00044
00045 static ColorMapEntry Palm8BitColormap[] = {
00046 { 255, 255, 255 }, { 255, 204, 255 }, { 255, 153, 255 }, { 255, 102, 255 },
00047 { 255, 51, 255 }, { 255, 0, 255 }, { 255, 255, 204 }, { 255, 204, 204 },
00048 { 255, 153, 204 }, { 255, 102, 204 }, { 255, 51, 204 }, { 255, 0, 204 },
00049 { 255, 255, 153 }, { 255, 204, 153 }, { 255, 153, 153 }, { 255, 102, 153 },
00050 { 255, 51, 153 }, { 255, 0, 153 }, { 204, 255, 255 }, { 204, 204, 255 },
00051 { 204, 153, 255 }, { 204, 102, 255 }, { 204, 51, 255 }, { 204, 0, 255 },
00052 { 204, 255, 204 }, { 204, 204, 204 }, { 204, 153, 204 }, { 204, 102, 204 },
00053 { 204, 51, 204 }, { 204, 0, 204 }, { 204, 255, 153 }, { 204, 204, 153 },
00054 { 204, 153, 153 }, { 204, 102, 153 }, { 204, 51, 153 }, { 204, 0, 153 },
00055 { 153, 255, 255 }, { 153, 204, 255 }, { 153, 153, 255 }, { 153, 102, 255 },
00056 { 153, 51, 255 }, { 153, 0, 255 }, { 153, 255, 204 }, { 153, 204, 204 },
00057 { 153, 153, 204 }, { 153, 102, 204 }, { 153, 51, 204 }, { 153, 0, 204 },
00058 { 153, 255, 153 }, { 153, 204, 153 }, { 153, 153, 153 }, { 153, 102, 153 },
00059 { 153, 51, 153 }, { 153, 0, 153 }, { 102, 255, 255 }, { 102, 204, 255 },
00060 { 102, 153, 255 }, { 102, 102, 255 }, { 102, 51, 255 }, { 102, 0, 255 },
00061 { 102, 255, 204 }, { 102, 204, 204 }, { 102, 153, 204 }, { 102, 102, 204 },
00062 { 102, 51, 204 }, { 102, 0, 204 }, { 102, 255, 153 }, { 102, 204, 153 },
00063 { 102, 153, 153 }, { 102, 102, 153 }, { 102, 51, 153 }, { 102, 0, 153 },
00064 { 51, 255, 255 }, { 51, 204, 255 }, { 51, 153, 255 }, { 51, 102, 255 },
00065 { 51, 51, 255 }, { 51, 0, 255 }, { 51, 255, 204 }, { 51, 204, 204 },
00066 { 51, 153, 204 }, { 51, 102, 204 }, { 51, 51, 204 }, { 51, 0, 204 },
00067 { 51, 255, 153 }, { 51, 204, 153 }, { 51, 153, 153 }, { 51, 102, 153 },
00068 { 51, 51, 153 }, { 51, 0, 153 }, { 0, 255, 255 }, { 0, 204, 255 },
00069 { 0, 153, 255 }, { 0, 102, 255 }, { 0, 51, 255 }, { 0, 0, 255 },
00070 { 0, 255, 204 }, { 0, 204, 204 }, { 0, 153, 204 }, { 0, 102, 204 },
00071 { 0, 51, 204 }, { 0, 0, 204 }, { 0, 255, 153 }, { 0, 204, 153 },
00072 { 0, 153, 153 }, { 0, 102, 153 }, { 0, 51, 153 }, { 0, 0, 153 },
00073 { 255, 255, 102 }, { 255, 204, 102 }, { 255, 153, 102 }, { 255, 102, 102 },
00074 { 255, 51, 102 }, { 255, 0, 102 }, { 255, 255, 51 }, { 255, 204, 51 },
00075 { 255, 153, 51 }, { 255, 102, 51 }, { 255, 51, 51 }, { 255, 0, 51 },
00076 { 255, 255, 0 }, { 255, 204, 0 }, { 255, 153, 0 }, { 255, 102, 0 },
00077 { 255, 51, 0 }, { 255, 0, 0 }, { 204, 255, 102 }, { 204, 204, 102 },
00078 { 204, 153, 102 }, { 204, 102, 102 }, { 204, 51, 102 }, { 204, 0, 102 },
00079 { 204, 255, 51 }, { 204, 204, 51 }, { 204, 153, 51 }, { 204, 102, 51 },
00080 { 204, 51, 51 }, { 204, 0, 51 }, { 204, 255, 0 }, { 204, 204, 0 },
00081 { 204, 153, 0 }, { 204, 102, 0 }, { 204, 51, 0 }, { 204, 0, 0 },
00082 { 153, 255, 102 }, { 153, 204, 102 }, { 153, 153, 102 }, { 153, 102, 102 },
00083 { 153, 51, 102 }, { 153, 0, 102 }, { 153, 255, 51 }, { 153, 204, 51 },
00084 { 153, 153, 51 }, { 153, 102, 51 }, { 153, 51, 51 }, { 153, 0, 51 },
00085 { 153, 255, 0 }, { 153, 204, 0 }, { 153, 153, 0 }, { 153, 102, 0 },
00086 { 153, 51, 0 }, { 153, 0, 0 }, { 102, 255, 102 }, { 102, 204, 102 },
00087 { 102, 153, 102 }, { 102, 102, 102 }, { 102, 51, 102 }, { 102, 0, 102 },
00088 { 102, 255, 51 }, { 102, 204, 51 }, { 102, 153, 51 }, { 102, 102, 51 },
00089 { 102, 51, 51 }, { 102, 0, 51 }, { 102, 255, 0 }, { 102, 204, 0 },
00090 { 102, 153, 0 }, { 102, 102, 0 }, { 102, 51, 0 }, { 102, 0, 0 },
00091 { 51, 255, 102 }, { 51, 204, 102 }, { 51, 153, 102 }, { 51, 102, 102 },
00092 { 51, 51, 102 }, { 51, 0, 102 }, { 51, 255, 51 }, { 51, 204, 51 },
00093 { 51, 153, 51 }, { 51, 102, 51 }, { 51, 51, 51 }, { 51, 0, 51 },
00094 { 51, 255, 0 }, { 51, 204, 0 }, { 51, 153, 0 }, { 51, 102, 0 },
00095 { 51, 51, 0 }, { 51, 0, 0 }, { 0, 255, 102 }, { 0, 204, 102 },
00096 { 0, 153, 102 }, { 0, 102, 102 }, { 0, 51, 102 }, { 0, 0, 102 },
00097 { 0, 255, 51 }, { 0, 204, 51 }, { 0, 153, 51 }, { 0, 102, 51 },
00098 { 0, 51, 51 }, { 0, 0, 51 }, { 0, 255, 0 }, { 0, 204, 0 },
00099 { 0, 153, 0 }, { 0, 102, 0 }, { 0, 51, 0 }, { 17, 17, 17 },
00100 { 34, 34, 34 }, { 68, 68, 68 }, { 85, 85, 85 }, { 119, 119, 119 },
00101 { 136, 136, 136 }, { 170, 170, 170 }, { 187, 187, 187 }, { 221, 221, 221 },
00102 { 238, 238, 238 }, { 192, 192, 192 }, { 128, 0, 0 }, { 128, 0, 128 },
00103 { 0, 128, 0 }, { 0, 128, 128 }, { 0, 0, 0 }, { 0, 0, 0 },
00104 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
00105 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
00106 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
00107 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
00108 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
00109 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }};
00110
00111 static ColorMapEntry Palm1BitColormap[] = {{ 255, 255, 255 }, { 0, 0, 0 }};
00112
00113 static ColorMapEntry Palm2BitColormap[] = {
00114 { 255, 255, 255 }, { 192, 192, 192 }, { 128, 128, 128 }, { 0, 0, 0 }};
00115
00116 static ColorMapEntry Palm4BitColormap[] = {
00117 { 255, 255, 255 }, { 238, 238, 238 }, { 221, 221, 221 }, { 204, 204, 204 },
00118 { 187, 187, 187 }, { 170, 170, 170 }, { 153, 153, 153 }, { 136, 136, 136 },
00119 { 119, 119, 119 }, { 102, 102, 102 }, { 85, 85, 85 }, { 68, 68, 68 },
00120 { 51, 51, 51 }, { 34, 34, 34 }, { 17, 17, 17 }, { 0, 0, 0 }};
00121
00122 QImage* Palm2QImage
00123 (unsigned char *image_bytes_in, int byte_count_in)
00124 {
00125 unsigned int width, height, bytes_per_row, flags, next_depth_offset;
00126 unsigned int bits_per_pixel, version, transparent_index, compression_type, i, j, inval, inbit, mask, incount;
00127 unsigned int palm_red_bits, palm_green_bits, palm_blue_bits;
00128 unsigned char *palm_ptr, *x_ptr, *imagedata, *inbyte, *rowbuf, *lastrow,
00129 *imagedatastart, *palmimage;
00130 ColorMapEntry *colormap;
00131
00132 palmimage = image_bytes_in;
00133 width = READ_BIGENDIAN_SHORT(palmimage + 0);
00134 height = READ_BIGENDIAN_SHORT(palmimage + 2);
00135 bytes_per_row = READ_BIGENDIAN_SHORT(palmimage + 4);
00136 flags = READ_BIGENDIAN_SHORT(palmimage + 6);
00137 bits_per_pixel = palmimage[8];
00138 version = palmimage[9];
00139 next_depth_offset = READ_BIGENDIAN_SHORT(palmimage + 10);
00140 transparent_index = palmimage[12];
00141 compression_type = palmimage[13];
00142
00143
00144 #if 0
00145
00146 #endif
00147
00148 if (compression_type == PALM_COMPRESSION_PACKBITS) {
00149
00150 return NULL;
00151 } else if ((compression_type != PALM_COMPRESSION_NONE) &&
00152 (compression_type != PALM_COMPRESSION_RLE) &&
00153 (compression_type != PALM_COMPRESSION_SCANLINE)) {
00154
00155 return NULL;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 if (flags & PALM_HAS_COLORMAP_FLAG) {
00172
00173 return NULL;
00174 } else if (bits_per_pixel == 1) {
00175 colormap = Palm1BitColormap;
00176 imagedatastart = palmimage + 16;
00177 } else if (bits_per_pixel == 2) {
00178 colormap = Palm2BitColormap;
00179 imagedatastart = palmimage + 16;
00180 } else if (bits_per_pixel == 4) {
00181 colormap = Palm4BitColormap;
00182 imagedatastart = palmimage + 16;
00183 } else if (bits_per_pixel == 8) {
00184 colormap = Palm8BitColormap;
00185 imagedatastart = palmimage + 16;
00186 } else if (bits_per_pixel == 16 && (flags & PALM_DIRECT_COLOR_FLAG)) {
00187 colormap = NULL;
00188 palm_red_bits = palmimage[16];
00189 palm_green_bits = palmimage[17];
00190 palm_blue_bits = palmimage[18];
00191
00192 if (palm_blue_bits > 8 || palm_green_bits > 8 || palm_red_bits > 8) {
00193
00194 return NULL;
00195 }
00196 if (bits_per_pixel > (8 * sizeof(unsigned long))) {
00197
00198 return NULL;
00199 }
00200 imagedatastart = palmimage + 24;
00201 } else {
00202
00203 return NULL;
00204 }
00205
00206 #ifndef USEQPE
00207 QImage* qimage = new QImage(width, height, 32);
00208 #else
00209 QImage* qimage = new QImage(width, height, 16);
00210 #endif
00211
00212
00213 rowbuf = new unsigned char[bytes_per_row * width];
00214 lastrow = new unsigned char[bytes_per_row * width];
00215
00216 for (i=0, palm_ptr = imagedatastart , x_ptr = imagedata; i < height; ++i) {
00217
00218
00219
00220 if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_RLE)) {
00221 for (j = 0; j < bytes_per_row; ) {
00222 incount = *palm_ptr++;
00223 inval = *palm_ptr++;
00224 memset(rowbuf + j, inval, incount);
00225 j += incount;
00226 }
00227 } else if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_SCANLINE)) {
00228 for (j = 0; j < bytes_per_row; j += 8) {
00229 incount = *palm_ptr++;
00230 inval = ((bytes_per_row - j) < 8) ? (bytes_per_row - j) : 8;
00231 for (inbit = 0; inbit < inval; inbit += 1) {
00232 if (incount & (1 << (7 - inbit)))
00233 rowbuf[j + inbit] = *palm_ptr++;
00234 else
00235 rowbuf[j + inbit] = lastrow[j + inbit];
00236 }
00237 }
00238 memcpy (lastrow, rowbuf, bytes_per_row);
00239 } else if (((flags & PALM_IS_COMPRESSED_FLAG) &&
00240 (compression_type == PALM_COMPRESSION_NONE)) ||
00241 ((flags & PALM_IS_COMPRESSED_FLAG) == 0))
00242 {
00243 memcpy (rowbuf, palm_ptr, bytes_per_row);
00244 palm_ptr += bytes_per_row;
00245 }
00246 else {
00247 qDebug("Case 4");
00248 qDebug("Is compressed:%s", ((flags & PALM_IS_COMPRESSED_FLAG) == 0) ? "false" : "true");
00249 qDebug("Has colourmap:%s", ((flags & PALM_HAS_COLORMAP_FLAG) == 0) ? "false" : "true");
00250 qDebug("Has transparency:%s", ((flags & PALM_HAS_TRANSPARENCY_FLAG) == 0) ? "false" : "true");
00251 qDebug("Direct colour:%s", ((flags & PALM_DIRECT_COLOR_FLAG) == 0) ? "false" : "true");
00252 qDebug("four byte field:%s", ((flags & PALM_4_BYTE_FIELD_FLAG) == 0) ? "false" : "true");
00253 memcpy (rowbuf, palm_ptr, bytes_per_row);
00254 palm_ptr += bytes_per_row;
00255 }
00256
00257 if (colormap) {
00258 mask = (1 << bits_per_pixel) - 1;
00259 for (inbit = 8 - bits_per_pixel, inbyte = rowbuf, j = 0; j < width; ++j) {
00260 inval = ((*inbyte) & (mask << inbit)) >> inbit;
00261
00262 if ((bits_per_pixel == 8) && (inval == 0xFF)) inval = 231;
00263
00264 QRgb colour = qRgb(colormap[inval].red, colormap[inval].green, colormap[inval].blue);
00265 qimage->setPixel(j, i, colour);
00266 if (!inbit) {
00267 ++inbyte;
00268 inbit = 8 - bits_per_pixel;
00269 } else {
00270 inbit -= bits_per_pixel;
00271 }
00272 }
00273 } else if (!colormap &&
00274 bits_per_pixel == 16) {
00275 for (inbyte = rowbuf, j = 0; j < width; ++j) {
00276 inval = ((unsigned short)inbyte[0] << (unsigned short)8) | inbyte[1];
00277
00278
00279
00280
00281
00282
00283
00284
00285 QRgb colour = qRgb(
00286 ((inval >> (bits_per_pixel - palm_red_bits)) & ((1 << palm_red_bits) - 1)) << (8-palm_red_bits),
00287 ((inval >> palm_blue_bits) & ((1 << palm_green_bits) - 1)) << (8-palm_green_bits),
00288 ((inval >> 0) & ((1 << palm_blue_bits) - 1)) << (8-palm_blue_bits));
00289 qimage->setPixel(j, i, colour);
00290 inbyte += 2;
00291 }
00292 }
00293 }
00294
00295 delete [] rowbuf;
00296 delete [] lastrow;
00297
00298 return qimage;
00299 }