00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "cdjpeg.h"
00023
00024 #ifdef RLE_SUPPORTED
00025
00026
00027
00028 #include <rle.h>
00029
00030
00031
00032
00033
00034
00035 #if BITS_IN_JSAMPLE != 8
00036 Sorry, this code only copes with 8-bit JSAMPLEs.
00037 #endif
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 typedef enum
00052 { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 typedef struct _rle_source_struct * rle_source_ptr;
00063
00064 typedef struct _rle_source_struct {
00065 struct cjpeg_source_struct pub;
00066
00067 rle_kind visual;
00068 jvirt_sarray_ptr image;
00069 JDIMENSION row;
00070 rle_hdr header;
00071 rle_pixel** rle_row;
00072
00073 } rle_source_struct;
00074
00075
00076
00077
00078
00079
00080 METHODDEF(void)
00081 start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00082 {
00083 rle_source_ptr source = (rle_source_ptr) sinfo;
00084 JDIMENSION width, height;
00085 #ifdef PROGRESS_REPORT
00086 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
00087 #endif
00088
00089
00090 source->header = *rle_hdr_init(NULL);
00091 source->header.rle_file = source->pub.input_file;
00092 switch (rle_get_setup(&(source->header))) {
00093 case RLE_SUCCESS:
00094
00095 break;
00096 case RLE_NOT_RLE:
00097 ERREXIT(cinfo, JERR_RLE_NOT);
00098 break;
00099 case RLE_NO_SPACE:
00100 ERREXIT(cinfo, JERR_RLE_MEM);
00101 break;
00102 case RLE_EMPTY:
00103 ERREXIT(cinfo, JERR_RLE_EMPTY);
00104 break;
00105 case RLE_EOF:
00106 ERREXIT(cinfo, JERR_RLE_EOF);
00107 break;
00108 default:
00109 ERREXIT(cinfo, JERR_RLE_BADERROR);
00110 break;
00111 }
00112
00113
00114
00115 width = source->header.xmax - source->header.xmin + 1;
00116 height = source->header.ymax - source->header.ymin + 1;
00117 source->header.xmin = 0;
00118 source->header.xmax = width-1;
00119
00120 cinfo->image_width = width;
00121 cinfo->image_height = height;
00122 cinfo->data_precision = 8;
00123
00124 if (source->header.ncolors == 1 && source->header.ncmap == 0) {
00125 source->visual = GRAYSCALE;
00126 TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height);
00127 } else if (source->header.ncolors == 1 && source->header.ncmap == 1) {
00128 source->visual = MAPPEDGRAY;
00129 TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height,
00130 1 << source->header.cmaplen);
00131 } else if (source->header.ncolors == 1 && source->header.ncmap == 3) {
00132 source->visual = PSEUDOCOLOR;
00133 TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height,
00134 1 << source->header.cmaplen);
00135 } else if (source->header.ncolors == 3 && source->header.ncmap == 3) {
00136 source->visual = TRUECOLOR;
00137 TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height,
00138 1 << source->header.cmaplen);
00139 } else if (source->header.ncolors == 3 && source->header.ncmap == 0) {
00140 source->visual = DIRECTCOLOR;
00141 TRACEMS2(cinfo, 1, JTRC_RLE, width, height);
00142 } else
00143 ERREXIT(cinfo, JERR_RLE_UNSUPPORTED);
00144
00145 if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) {
00146 cinfo->in_color_space = JCS_GRAYSCALE;
00147 cinfo->input_components = 1;
00148 } else {
00149 cinfo->in_color_space = JCS_RGB;
00150 cinfo->input_components = 3;
00151 }
00152
00153
00154
00155
00156
00157 if (source->visual != GRAYSCALE) {
00158 source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray)
00159 ((j_common_ptr) cinfo, JPOOL_IMAGE,
00160 (JDIMENSION) width, (JDIMENSION) cinfo->input_components);
00161 }
00162
00163
00164 source->image = (*cinfo->mem->request_virt_sarray)
00165 ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
00166 (JDIMENSION) (width * source->header.ncolors),
00167 (JDIMENSION) height, (JDIMENSION) 1);
00168
00169 #ifdef PROGRESS_REPORT
00170 if (progress != NULL) {
00171
00172 progress->total_extra_passes++;
00173 }
00174 #endif
00175
00176 source->pub.buffer_height = 1;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 METHODDEF(JDIMENSION)
00187 get_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00188 {
00189 rle_source_ptr source = (rle_source_ptr) sinfo;
00190
00191 source->row--;
00192 source->pub.buffer = (*cinfo->mem->access_virt_sarray)
00193 ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE);
00194
00195 return 1;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 METHODDEF(JDIMENSION)
00205 get_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00206 {
00207 rle_source_ptr source = (rle_source_ptr) sinfo;
00208 JSAMPROW src_row, dest_row;
00209 JDIMENSION col;
00210 rle_map *colormap;
00211 int val;
00212
00213 colormap = source->header.cmap;
00214 dest_row = source->pub.buffer[0];
00215 source->row--;
00216 src_row = * (*cinfo->mem->access_virt_sarray)
00217 ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE);
00218
00219 for (col = cinfo->image_width; col > 0; col--) {
00220 val = GETJSAMPLE(*src_row++);
00221 *dest_row++ = (JSAMPLE) (colormap[val ] >> 8);
00222 *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8);
00223 *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8);
00224 }
00225
00226 return 1;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 METHODDEF(JDIMENSION)
00241 load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00242 {
00243 rle_source_ptr source = (rle_source_ptr) sinfo;
00244 JDIMENSION row, col;
00245 JSAMPROW scanline, red_ptr, green_ptr, blue_ptr;
00246 rle_pixel **rle_row;
00247 rle_map *colormap;
00248 char channel;
00249 #ifdef PROGRESS_REPORT
00250 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
00251 #endif
00252
00253 colormap = source->header.cmap;
00254 rle_row = source->rle_row;
00255
00256
00257
00258
00259
00260 RLE_CLR_BIT(source->header, RLE_ALPHA);
00261
00262 #ifdef PROGRESS_REPORT
00263 if (progress != NULL) {
00264 progress->pub.pass_limit = cinfo->image_height;
00265 progress->pub.pass_counter = 0;
00266 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00267 }
00268 #endif
00269
00270 switch (source->visual) {
00271
00272 case GRAYSCALE:
00273 case PSEUDOCOLOR:
00274 for (row = 0; row < cinfo->image_height; row++) {
00275 rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
00276 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00277 rle_getrow(&source->header, rle_row);
00278 #ifdef PROGRESS_REPORT
00279 if (progress != NULL) {
00280 progress->pub.pass_counter++;
00281 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00282 }
00283 #endif
00284 }
00285 break;
00286
00287 case MAPPEDGRAY:
00288 case TRUECOLOR:
00289 for (row = 0; row < cinfo->image_height; row++) {
00290 scanline = * (*cinfo->mem->access_virt_sarray)
00291 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00292 rle_row = source->rle_row;
00293 rle_getrow(&source->header, rle_row);
00294
00295 for (col = 0; col < cinfo->image_width; col++) {
00296 for (channel = 0; channel < source->header.ncolors; channel++) {
00297 *scanline++ = (JSAMPLE)
00298 (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8);
00299 }
00300 }
00301
00302 #ifdef PROGRESS_REPORT
00303 if (progress != NULL) {
00304 progress->pub.pass_counter++;
00305 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00306 }
00307 #endif
00308 }
00309 break;
00310
00311 case DIRECTCOLOR:
00312 for (row = 0; row < cinfo->image_height; row++) {
00313 scanline = * (*cinfo->mem->access_virt_sarray)
00314 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00315 rle_getrow(&source->header, rle_row);
00316
00317 red_ptr = rle_row[0];
00318 green_ptr = rle_row[1];
00319 blue_ptr = rle_row[2];
00320
00321 for (col = cinfo->image_width; col > 0; col--) {
00322 *scanline++ = *red_ptr++;
00323 *scanline++ = *green_ptr++;
00324 *scanline++ = *blue_ptr++;
00325 }
00326
00327 #ifdef PROGRESS_REPORT
00328 if (progress != NULL) {
00329 progress->pub.pass_counter++;
00330 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00331 }
00332 #endif
00333 }
00334 }
00335
00336 #ifdef PROGRESS_REPORT
00337 if (progress != NULL)
00338 progress->completed_extra_passes++;
00339 #endif
00340
00341
00342 if (source->visual == PSEUDOCOLOR) {
00343 source->pub.buffer = source->rle_row;
00344 source->pub.get_pixel_rows = get_pseudocolor_row;
00345 } else {
00346 source->pub.get_pixel_rows = get_rle_row;
00347 }
00348 source->row = cinfo->image_height;
00349
00350
00351 return (*source->pub.get_pixel_rows) (cinfo, sinfo);
00352 }
00353
00354
00355
00356
00357
00358
00359 METHODDEF(void)
00360 finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00361 {
00362
00363 }
00364
00365
00366
00367
00368
00369
00370 GLOBAL(cjpeg_source_ptr)
00371 jinit_read_rle (j_compress_ptr cinfo)
00372 {
00373 rle_source_ptr source;
00374
00375
00376 source = (rle_source_ptr)
00377 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00378 SIZEOF(rle_source_struct));
00379
00380 source->pub.start_input = start_input_rle;
00381 source->pub.finish_input = finish_input_rle;
00382 source->pub.get_pixel_rows = load_image;
00383
00384 return (cjpeg_source_ptr) source;
00385 }
00386
00387 #endif