00001
00014 #include "jpeg_tool.h"
00015 #include "jbxl_state.h"
00016
00017
00018 #ifdef ENABLE_JPEGLIB
00019
00020
00033 JPEGImage read_jpeg_file(const char* fname)
00034 {
00035 JPEGImage jp;
00036 int xs, ys, col;
00037 FILE* fp;
00038
00039 struct jpeg_decompress_struct jdat;
00040 struct jpeg_error_mgr jerr;
00041
00042 memset(&jp, 0, sizeof(JPEGImage));
00043
00044 jdat.err = jpeg_std_error(&jerr);
00045 jpeg_create_decompress(&jdat);
00046
00047
00048
00049
00050
00051
00052 fp = fopen(fname, "rb");
00053 if (fp==NULL) {
00054 jp.state = JBXL_GRAPH_OPFILE_ERROR;
00055 return jp;
00056 }
00057 jpeg_stdio_src(&jdat, fp);
00058 jpeg_read_header(&jdat, TRUE);
00059 jpeg_start_decompress(&jdat);
00060
00061 xs = jdat.output_width;
00062 ys = jdat.output_height;
00063 col = jdat.output_components;
00064 if (xs<=0 || ys<=0 || col<=0) {
00065 jpeg_destroy_decompress(&jdat);
00066 fclose(fp);
00067 jp.state = JBXL_GRAPH_HEADER_ERROR;
00068 return jp;
00069 }
00070
00071 jp = make_JPEGImage(xs, ys, col);
00072 if (jp.gp==NULL) {
00073 jpeg_destroy_decompress(&jdat);
00074 fclose(fp);
00075 jp.state = JBXL_GRAPH_MEMORY_ERROR;
00076 return jp;
00077 }
00078
00079 int rmn = jdat.output_height;
00080 while(rmn>0) {
00081 jpeg_read_scanlines(&jdat, jp.img+jdat.output_scanline, rmn);
00082 rmn = jdat.output_height - jdat.output_scanline;
00083 }
00084 jpeg_finish_decompress (&jdat);
00085 jpeg_destroy_decompress(&jdat);
00086
00087 fclose(fp);
00088
00089 return jp;
00090 }
00091
00092
00093
00110 int write_jpeg_file(const char* fname, JPEGImage jp, int qulty)
00111 {
00112 FILE* fp;
00113 struct jpeg_compress_struct jdat;
00114 struct jpeg_error_mgr jerr;
00115
00116
00117 if (fname==NULL) return JBXL_GRAPH_IVDARG_ERROR;
00118 if (jp.col!=1 && jp.col!=3) return JBXL_GRAPH_IVDARG_ERROR;
00119 if (jp.gp==NULL || jp.img==NULL) return JBXL_GRAPH_NODATA_ERROR;
00120
00121 if (qulty>100) qulty = 100;
00122 else if (qulty<0) qulty = 0;
00123
00124
00125 fp = fopen(fname, "wb");
00126 if (fp==NULL) {
00127 return JBXL_GRAPH_OPFILE_ERROR;
00128 }
00129
00130 jdat.err = jpeg_std_error(&jerr);
00131 jpeg_create_compress(&jdat);
00132
00133
00134
00135
00136
00137
00138 jpeg_stdio_dest(&jdat, fp);
00139
00140 jdat.image_width = jp.xs;
00141 jdat.image_height = jp.ys;
00142 jdat.input_components = jp.col;
00143 if (jp.col==1) jdat.in_color_space = JCS_GRAYSCALE;
00144 else jdat.in_color_space = JCS_RGB;
00145
00146 jpeg_set_quality (&jdat, qulty, TRUE);
00147 jpeg_set_defaults(&jdat);
00148
00149 jpeg_start_compress (&jdat, TRUE);
00150 jpeg_write_scanlines(&jdat, jp.img, jp.ys);
00151 jpeg_finish_compress(&jdat);
00152
00153 jpeg_destroy_compress(&jdat);
00154 fclose(fp);
00155
00156 return 0;
00157 }
00158
00159
00160
00177 int write_jpeg_mem(unsigned char** buf, unsigned long* len, JPEGImage jp, int qulty)
00178 {
00179 struct jpeg_compress_struct jdat;
00180 struct jpeg_error_mgr jerr;
00181
00182 if (buf==NULL || len==NULL) return JBXL_GRAPH_IVDARG_ERROR;
00183 if (jp.col!=1 && jp.col!=3) return JBXL_GRAPH_IVDARG_ERROR;
00184 if (jp.gp==NULL || jp.img==NULL) return JBXL_GRAPH_NODATA_ERROR;
00185
00186 *len = jp.xs*jp.ys*jp.col;
00187 if (*len<=0) return JBXL_GRAPH_IVDARG_ERROR;
00188
00189 if (qulty>100) qulty = 100;
00190 else if (qulty<0) qulty = 0;
00191
00192 *buf = (unsigned char*)malloc(*len);
00193 if (*buf==NULL) {
00194 return JBXL_GRAPH_MEMORY_ERROR;
00195 }
00196
00197 jdat.err = jpeg_std_error(&jerr);
00198 jpeg_create_compress(&jdat);
00199
00200 jpeg_mem_dest(&jdat, buf, len);
00201
00202 jdat.image_width = jp.xs;
00203 jdat.image_height = jp.ys;
00204 jdat.input_components = jp.col;
00205 if (jp.col==1) jdat.in_color_space = JCS_GRAYSCALE;
00206 else jdat.in_color_space = JCS_RGB;
00207
00208 jpeg_set_quality (&jdat, qulty, TRUE);
00209 jpeg_set_defaults(&jdat);
00210
00211 jpeg_start_compress (&jdat, TRUE);
00212 jpeg_write_scanlines(&jdat, jp.img, jp.ys);
00213 jpeg_finish_compress(&jdat);
00214 jpeg_destroy_compress(&jdat);
00215
00216 if (*len<=0) {
00217 freeNull(*buf);
00218 return JBXL_GRAPH_ERROR;
00219 }
00220
00221 return 0;
00222 }
00223
00224
00225
00231 WSGraph JPEGImage2WSGraph(JPEGImage jp)
00232 {
00233 WSGraph vp;
00234 int i, j, k, yp, zp;
00235
00236 memset(&vp, 0, sizeof(WSGraph));
00237 if (jp.gp==NULL || jp.img==NULL) {
00238 vp.state = JBXL_GRAPH_NODATA_ERROR;
00239 return vp;
00240 }
00241
00242 vp = make_WSGraph(jp.xs, jp.ys, jp.col);
00243 if (vp.gp==NULL) return vp;
00244
00245 for (k=0; k<jp.col; k++) {
00246 zp = k*jp.xs*jp.ys;
00247 for (j=0; j<jp.ys; j++) {
00248 yp = zp + j*jp.xs;
00249 for (i=0; i<jp.xs; i++) {
00250 vp.gp[yp + i] = (sWord)(jp.img[j][i*jp.col + k]);
00251 }
00252 }
00253 }
00254
00255 vp.state = JBXL_NORMAL;
00256 return vp;
00257 }
00258
00259
00260
00266 BSGraph JPEGImage2BSGraph(JPEGImage jp)
00267 {
00268 BSGraph vp;
00269 int i, j, k, yp, zp;
00270
00271 memset(&vp, 0, sizeof(BSGraph));
00272 if (jp.gp==NULL || jp.img==NULL) {
00273 vp.state = JBXL_GRAPH_NODATA_ERROR;
00274 return vp;
00275 }
00276
00277 vp = make_BSGraph(jp.xs, jp.ys, jp.col);
00278 if (vp.gp==NULL) return vp;
00279
00280 for (k=0; k<jp.col; k++) {
00281 zp = k*jp.xs*jp.ys;
00282 for (j=0; j<jp.ys; j++) {
00283 yp = zp + j*jp.xs;
00284 for (i=0; i<jp.xs; i++) {
00285 vp.gp[yp + i] = (uByte)(jp.img[j][i*jp.col + k]);
00286 }
00287 }
00288 }
00289
00290 vp.state = JBXL_NORMAL;
00291 return vp;
00292 }
00293
00294
00295
00299 JPEGImage WSGraph2JPEGImage(WSGraph vp)
00300 {
00301 JPEGImage jp;
00302 int i, j, k, yp, zp;
00303
00304 memset(&jp, 0, sizeof(JPEGImage));
00305 if (vp.gp==NULL) {
00306 jp.state = JBXL_GRAPH_NODATA_ERROR;
00307 return jp;
00308 }
00309
00310 jp = make_JPEGImage(vp.xs, vp.ys, vp.zs);
00311 if (jp.gp==NULL || jp.img==NULL) return jp;
00312
00313 for (k=0; k<vp.zs; k++) {
00314 zp = k*vp.xs*vp.ys;
00315 for (j=0; j<vp.ys; j++) {
00316 yp = zp + j*vp.xs;
00317 for (i=0; i<vp.xs; i++) {
00318 jp.img[j][i*vp.zs + k] = vp.gp[yp + i];
00319 }
00320 }
00321 }
00322
00323 return jp;
00324 }
00325
00326
00327
00331 JPEGImage BSGraph2JPEGImage(BSGraph vp)
00332 {
00333 JPEGImage jp;
00334 int i, j, k, yp, zp;
00335
00336 memset(&jp, 0, sizeof(JPEGImage));
00337 if (vp.gp==NULL) {
00338 jp.state = JBXL_GRAPH_NODATA_ERROR;
00339 return jp;
00340 }
00341
00342 jp = make_JPEGImage(vp.xs, vp.ys, vp.zs);
00343 if (jp.gp==NULL || jp.img==NULL) return jp;
00344
00345 for (k=0; k<vp.zs; k++) {
00346 zp = k*vp.xs*vp.ys;
00347 for (j=0; j<vp.ys; j++) {
00348 yp = zp + j*vp.xs;
00349 for (i=0; i<vp.xs; i++) {
00350 jp.img[j][i*vp.zs + k] = vp.gp[yp + i];
00351 }
00352 }
00353 }
00354
00355 return jp;
00356 }
00357
00358
00359
00363 JPEGImage make_JPEGImage(int xs, int ys, int col)
00364 {
00365 int j;
00366 JPEGImage jp;
00367
00368 memset(&jp, 0, sizeof(JPEGImage));
00369 if (xs==0 || ys==0) {
00370 jp.state = JBXL_GRAPH_IVDARG_ERROR;
00371 return jp;
00372 }
00373 if (col<1) col = 3;
00374
00375 jp.img = (JSAMPARRAY)malloc(sizeof(JSAMPROW)*ys);
00376 if (jp.img==NULL) {
00377 jp.state = JBXL_GRAPH_MEMORY_ERROR;
00378 return jp;
00379 }
00380
00381 jp.gp = (JSAMPLE*)malloc(sizeof(JSAMPLE)*col*xs*ys);
00382 if (jp.gp==NULL) {
00383 freeNull(jp.img);
00384 jp.state = JBXL_GRAPH_MEMORY_ERROR;
00385 return jp;
00386 }
00387
00388 for (j=0; j<ys; j++) {
00389 jp.img[j] = (JSAMPROW)&jp.gp[j*col*xs];
00390 }
00391
00392 jp.xs = xs;
00393 jp.ys = ys;
00394 jp.col = col;
00395
00396 return jp;
00397 }
00398
00399
00400
00404 void free_JPEGImage(JPEGImage* jp)
00405 {
00406 if (jp==NULL) return;
00407
00408 freeNull(jp->gp);
00409 freeNull(jp->img);
00410
00411 jp->xs = jp->ys = jp->col = 0;
00412 return;
00413 }
00414
00415
00416
00417
00419
00420
00421 #if JPEG_LIB_VERSION < 80
00422
00423
00424 METHODDEF(void) mem_init_destination(j_compress_ptr cinfo)
00425 {
00426 UNUSED(cinfo);
00427 }
00428
00429
00430
00431 METHODDEF(boolean) mem_empty_output_buffer(j_compress_ptr cinfo)
00432 {
00433 size_t nextsize;
00434 JOCTET * nextbuffer;
00435 my_mem_dest_ptr dest = (my_mem_dest_ptr)cinfo->dest;
00436
00437 nextsize = dest->bufsize * 2;
00438 nextbuffer = (JOCTET*)malloc(nextsize);
00439
00440 if (nextbuffer == NULL) return FALSE;
00441
00442 memcpy(nextbuffer, dest->buffer, dest->bufsize);
00443
00444 if (dest->newbuffer != NULL) free(dest->newbuffer);
00445
00446 dest->newbuffer = nextbuffer;
00447 dest->pub.next_output_byte = nextbuffer + dest->bufsize;
00448 dest->pub.free_in_buffer = dest->bufsize;
00449 dest->buffer = nextbuffer;
00450 dest->bufsize = nextsize;
00451
00452 return TRUE;
00453 }
00454
00455
00456
00457 METHODDEF(void) mem_term_destination(j_compress_ptr cinfo)
00458 {
00459 my_mem_dest_ptr dest = (my_mem_dest_ptr)cinfo->dest;
00460
00461 *dest->outbuffer = dest->buffer;
00462 *dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
00463 }
00464
00465
00466
00467 GLOBAL(void) jpeg_mem_dest(j_compress_ptr cinfo, unsigned char** buf, unsigned long* len)
00468 {
00469
00470 my_mem_dest_ptr dest;
00471
00472 if (cinfo->dest == NULL) {
00473 cinfo->dest = (struct jpeg_destination_mgr*)
00474 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(my_mem_destination_mgr));
00475 }
00476
00477 dest = (my_mem_dest_ptr)cinfo->dest;
00478 dest->pub.init_destination = mem_init_destination;
00479 dest->pub.empty_output_buffer = mem_empty_output_buffer;
00480 dest->pub.term_destination = mem_term_destination;
00481 dest->pub.next_output_byte = *buf;
00482 dest->pub.free_in_buffer = *len;
00483 dest->pub.next_output_byte = dest->buffer = *buf;
00484 dest->pub.free_in_buffer = dest->bufsize = *len;
00485 dest->outbuffer = buf;
00486 dest->outsize = len;
00487 dest->newbuffer = NULL;
00488 }
00489
00490 #endif // JPEG_LIB_VERSION
00491
00492 #endif // DISABLE_JPEGLIB
00493