JunkBox_Lib  1.10.2
jpeg_tool.c
Go to the documentation of this file.
1 
12 #include "jpeg_tool.h"
13 #include "jbxl_state.h"
14 
15 
16 #ifdef ENABLE_JPEG
17 
18 
31 JPEGImage read_jpeg_file(const char* fname)
32 {
33  JPEGImage jp;
34  int xs, ys, col;
35  FILE* fp;
36 
37  struct jpeg_decompress_struct jdat;
38  struct jpeg_error_mgr jerr;
39 
40  memset(&jp, 0, sizeof(JPEGImage));
41 
42  jdat.err = jpeg_std_error(&jerr);
43  jpeg_create_decompress(&jdat);
44 
45  // エラーハンドラ
46 /* jdat.client_data = "Client Data";
47  jerr.error_exit = jpeg_error_exit;
48  //jerr.output_message = print_message;
49 */
50  fp = fopen(fname, "rb");
51  if (fp==NULL) {
53  return jp;
54  }
55  jpeg_stdio_src(&jdat, fp);
56  jpeg_read_header(&jdat, TRUE);
57  jpeg_start_decompress(&jdat);
58 
59  xs = jdat.output_width;
60  ys = jdat.output_height;
61  col = jdat.output_components;
62  if (xs<=0 || ys<=0 || col<=0) {
63  jpeg_destroy_decompress(&jdat);
64  fclose(fp);
66  return jp;
67  }
68 
69  jp = make_JPEGImage(xs, ys, col);
70  if (jp.gp==NULL) {
71  jpeg_destroy_decompress(&jdat);
72  fclose(fp);
74  return jp;
75  }
76 
77  int rmn = jdat.output_height;
78  while(rmn>0) {
79  jpeg_read_scanlines(&jdat, jp.img+jdat.output_scanline, rmn);
80  rmn = jdat.output_height - jdat.output_scanline;
81  }
82  jpeg_finish_decompress (&jdat);
83  jpeg_destroy_decompress(&jdat);
84 
85  fclose(fp);
86 
87  return jp;
88 }
89 
90 
108 int write_jpeg_file(const char* fname, JPEGImage* jp, int qulty)
109 {
110  FILE* fp;
111  struct jpeg_compress_struct jdat;
112  struct jpeg_error_mgr jerr;
113 
114 
115  if (fname==NULL) return JBXL_GRAPH_IVDARG_ERROR;
116  if (jp->col!=1 && jp->col!=3) return JBXL_GRAPH_IVDCOLOR_ERROR;
117  if (jp->gp==NULL || jp->img==NULL) return JBXL_GRAPH_NODATA_ERROR;
118 
119  if (qulty>100) qulty = 100;
120  else if (qulty<0) qulty = 0;
121 
122 
123  fp = fopen(fname, "wb");
124  if (fp==NULL) {
126  }
127 
128  jdat.err = jpeg_std_error(&jerr);
129  jpeg_create_compress(&jdat);
130 
131  // エラーハンドラ
132 /* jdat.client_data = "Client Data";
133  jerr.error_exit = jpeg_error_exit;
134  //jerr.output_message = print_message;
135 */
136  jpeg_stdio_dest(&jdat, fp);
137 
138  jdat.image_width = jp->xs;
139  jdat.image_height = jp->ys;
140  jdat.input_components = jp->col;
141  if (jp->col==1) jdat.in_color_space = JCS_GRAYSCALE;
142  else jdat.in_color_space = JCS_RGB;
143 
144  jpeg_set_quality (&jdat, qulty, TRUE);
145  jpeg_set_defaults(&jdat);
146 
147  jpeg_start_compress (&jdat, TRUE);
148  jpeg_write_scanlines(&jdat, jp->img, jp->ys);
149  jpeg_finish_compress(&jdat);
150 
151  jpeg_destroy_compress(&jdat);
152  fclose(fp);
153 
154  return 0;
155 }
156 
157 
175 int write_jpeg_mem(unsigned char** buf, unsigned long* len, JPEGImage* jp, int qulty)
176 {
177  struct jpeg_compress_struct jdat;
178  struct jpeg_error_mgr jerr;
179 
180  if (buf==NULL || len==NULL) return JBXL_GRAPH_IVDARG_ERROR;
181  if (jp->col!=1 && jp->col!=3) return JBXL_GRAPH_IVDCOLOR_ERROR;
182  if (jp->gp==NULL || jp->img==NULL) return JBXL_GRAPH_NODATA_ERROR;
183 
184  *len = jp->xs*jp->ys*jp->col;
185  if (*len<=0) return JBXL_GRAPH_IVDARG_ERROR;
186 
187  if (qulty>100) qulty = 100;
188  else if (qulty<0) qulty = 0;
189 
190  *buf = (unsigned char*)malloc(*len);
191  if (*buf==NULL) {
193  }
194 
195  jdat.err = jpeg_std_error(&jerr);
196  jpeg_create_compress(&jdat);
197 
198  jpeg_mem_dest(&jdat, buf, len);
199 
200  jdat.image_width = jp->xs;
201  jdat.image_height = jp->ys;
202  jdat.input_components = jp->col;
203  if (jp->col==1) jdat.in_color_space = JCS_GRAYSCALE;
204  else jdat.in_color_space = JCS_RGB;
205 
206  jpeg_set_quality (&jdat, qulty, TRUE);
207  jpeg_set_defaults(&jdat);
208 
209  jpeg_start_compress (&jdat, TRUE);
210  jpeg_write_scanlines(&jdat, jp->img, jp->ys);
211  jpeg_finish_compress(&jdat);
212  jpeg_destroy_compress(&jdat);
213 
214  if (*len<=0) {
215  freeNull(*buf);
216  return JBXL_GRAPH_ERROR;
217  }
218 
219  return 0;
220 }
221 
222 
229 {
230  WSGraph vp;
231  int i, j, k, yp, zp;
232 
233  memset(&vp, 0, sizeof(WSGraph));
234  if (jp.gp==NULL || jp.img==NULL) {
236  return vp;
237  }
238 
239  vp = make_WSGraph(jp.xs, jp.ys, jp.col);
240  if (vp.gp==NULL) return vp;
241 
242  for (k=0; k<jp.col; k++) {
243  zp = k*jp.xs*jp.ys;
244  for (j=0; j<jp.ys; j++) {
245  yp = zp + j*jp.xs;
246  for (i=0; i<jp.xs; i++) {
247  vp.gp[yp + i] = (sWord)(jp.img[j][i*jp.col + k]); // チャンネルに分解
248  }
249  }
250  }
251 
252  vp.state = JBXL_NORMAL;
253  return vp;
254 }
255 
256 
263 {
264  BSGraph vp;
265  int i, j, k, yp, zp;
266 
267  memset(&vp, 0, sizeof(BSGraph));
268  if (jp.gp==NULL || jp.img==NULL) {
270  return vp;
271  }
272 
273  vp = make_BSGraph(jp.xs, jp.ys, jp.col);
274  if (vp.gp==NULL) return vp;
275 
276  for (k=0; k<jp.col; k++) {
277  zp = k*jp.xs*jp.ys;
278  for (j=0; j<jp.ys; j++) {
279  yp = zp + j*jp.xs;
280  for (i=0; i<jp.xs; i++) {
281  vp.gp[yp + i] = (uByte)(jp.img[j][i*jp.col + k]); // チャンネルに分解
282  }
283  }
284  }
285 
286  vp.state = JBXL_NORMAL;
287  return vp;
288 }
289 
290 
295 {
296  JPEGImage jp;
297  int i, j, k, yp, zp;
298 
299  memset(&jp, 0, sizeof(JPEGImage));
300  if (vp.gp==NULL) {
302  return jp;
303  }
304 
305  jp = make_JPEGImage(vp.xs, vp.ys, vp.zs);
306  if (jp.gp==NULL || jp.img==NULL) return jp;
307 
308  for (k=0; k<vp.zs; k++) {
309  zp = k*vp.xs*vp.ys;
310  for (j=0; j<vp.ys; j++) {
311  yp = zp + j*vp.xs;
312  for (i=0; i<vp.xs; i++) {
313  jp.img[j][i*vp.zs + k] = vp.gp[yp + i];
314  }
315  }
316  }
317 
318  return jp;
319 }
320 
321 
326 {
327  JPEGImage jp;
328  int i, j, k, yp, zp;
329 
330  memset(&jp, 0, sizeof(JPEGImage));
331  if (vp.gp==NULL) {
333  return jp;
334  }
335 
336  jp = make_JPEGImage(vp.xs, vp.ys, vp.zs);
337  if (jp.gp==NULL || jp.img==NULL) return jp;
338 
339  for (k=0; k<vp.zs; k++) {
340  zp = k*vp.xs*vp.ys;
341  for (j=0; j<vp.ys; j++) {
342  yp = zp + j*vp.xs;
343  for (i=0; i<vp.xs; i++) {
344  jp.img[j][i*vp.zs + k] = vp.gp[yp + i];
345  }
346  }
347  }
348 
349  return jp;
350 }
351 
352 
356 JPEGImage make_JPEGImage(int xs, int ys, int col)
357 {
358  int j;
359  JPEGImage jp;
360 
361  memset(&jp, 0, sizeof(JPEGImage));
362  if (xs==0 || ys==0) {
364  return jp;
365  }
366  if (col<1) col = 3;
367 
368  jp.img = (JSAMPARRAY)malloc(sizeof(JSAMPROW)*ys);
369  if (jp.img==NULL) {
371  return jp;
372  }
373 
374  jp.gp = (JSAMPLE*)malloc(sizeof(JSAMPLE)*col*xs*ys);
375  if (jp.gp==NULL) {
376  freeNull(jp.img);
378  return jp;
379  }
380 
381  for (j=0; j<ys; j++) {
382  jp.img[j] = (JSAMPROW)&jp.gp[j*col*xs];
383  }
384 
385  jp.xs = xs;
386  jp.ys = ys;
387  jp.col = col;
388 
389  return jp;
390 }
391 
392 
397 {
398  if (jp==NULL) return;
399 
400  freeNull(jp->gp);
401  freeNull(jp->img);
402 
403  jp->xs = jp->ys = jp->col = 0;
404  return;
405 }
406 
407 
408 
410 // for libjpeg 6b (http://www.ijg.org/)
411 //
412 #if JPEG_LIB_VERSION < 80
413 
414 
415 METHODDEF(void) mem_init_destination(j_compress_ptr cinfo)
416 {
417  UNUSED(cinfo);
418 }
419 
420 
421 METHODDEF(boolean) mem_empty_output_buffer(j_compress_ptr cinfo)
422 {
423  size_t nextsize;
424  JOCTET * nextbuffer;
425  my_mem_dest_ptr dest = (my_mem_dest_ptr)cinfo->dest;
426 
427  nextsize = dest->bufsize * 2;
428  nextbuffer = (JOCTET*)malloc(nextsize);
429 
430  if (nextbuffer == NULL) return FALSE;
431 
432  memcpy(nextbuffer, dest->buffer, dest->bufsize);
433 
434  if (dest->newbuffer != NULL) free(dest->newbuffer);
435 
436  dest->newbuffer = nextbuffer;
437  dest->pub.next_output_byte = nextbuffer + dest->bufsize;
438  dest->pub.free_in_buffer = dest->bufsize;
439  dest->buffer = nextbuffer;
440  dest->bufsize = nextsize;
441 
442  return TRUE;
443 }
444 
445 
446 METHODDEF(void) mem_term_destination(j_compress_ptr cinfo)
447 {
448  my_mem_dest_ptr dest = (my_mem_dest_ptr)cinfo->dest;
449 
450  *dest->outbuffer = dest->buffer;
451  *dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
452 }
453 
454 
455 GLOBAL(void) jpeg_mem_dest(j_compress_ptr cinfo, unsigned char** buf, unsigned long* len)
456 {
457  //memory_dest_ptr dest;
458  my_mem_dest_ptr dest;
459 
460  if (cinfo->dest == NULL) { // first time for this JPEG object?
461  cinfo->dest = (struct jpeg_destination_mgr*)
462  (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(my_mem_destination_mgr));
463  }
464 
465  dest = (my_mem_dest_ptr)cinfo->dest;
466  dest->pub.init_destination = mem_init_destination;
467  dest->pub.empty_output_buffer = mem_empty_output_buffer;
468  dest->pub.term_destination = mem_term_destination;
469  dest->pub.next_output_byte = *buf;
470  dest->pub.free_in_buffer = *len;
471  dest->pub.next_output_byte = dest->buffer = *buf;
472  dest->pub.free_in_buffer = dest->bufsize = *len;
473  dest->outbuffer = buf;
474  dest->outsize = len;
475  dest->newbuffer = NULL;
476 }
477 
478 
479 #endif // JPEG_LIB_VERSION
480 #endif // DISABLE_JPEG
481 
#define UNUSED(x)
Definition: common.h:264
short sWord
2Byte
Definition: common.h:335
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
unsigned char uByte
1Byte
Definition: common.h:332
BSGraph make_BSGraph(int xs, int ys, int zs)
Definition: gdata.c:66
WSGraph make_WSGraph(int xs, int ys, int zs)
Definition: gdata.c:108
JunkBox_Lib 状態ヘッダ
#define JBXL_GRAPH_IVDARG_ERROR
無効な引数
Definition: jbxl_state.h:178
#define JBXL_GRAPH_NODATA_ERROR
データが無い
Definition: jbxl_state.h:171
#define JBXL_GRAPH_ERROR
GRAPH ライブラリーのエラー
Definition: jbxl_state.h:167
#define JBXL_GRAPH_OPFILE_ERROR
ファイルのオープンエラー
Definition: jbxl_state.h:173
#define JBXL_GRAPH_IVDCOLOR_ERROR
無効なカラー指定
Definition: jbxl_state.h:183
#define JBXL_NORMAL
正常
Definition: jbxl_state.h:32
#define JBXL_GRAPH_HEADER_ERROR
画像ヘッダーのエラー
Definition: jbxl_state.h:169
#define JBXL_GRAPH_MEMORY_ERROR
メモリエラー
Definition: jbxl_state.h:170
JPEGImage WSGraph2JPEGImage(WSGraph vp)
Definition: jpeg_tool.c:294
void free_JPEGImage(JPEGImage *jp)
Definition: jpeg_tool.c:396
METHODDEF(void)
Definition: jpeg_tool.c:415
int write_jpeg_mem(unsigned char **buf, unsigned long *len, JPEGImage *jp, int qulty)
Definition: jpeg_tool.c:175
BSGraph JPEGImage2BSGraph(JPEGImage jp)
Definition: jpeg_tool.c:262
JPEGImage BSGraph2JPEGImage(BSGraph vp)
Definition: jpeg_tool.c:325
JPEGImage make_JPEGImage(int xs, int ys, int col)
Definition: jpeg_tool.c:356
GLOBAL(void)
Definition: jpeg_tool.c:455
int write_jpeg_file(const char *fname, JPEGImage *jp, int qulty)
Definition: jpeg_tool.c:108
WSGraph JPEGImage2WSGraph(JPEGImage jp)
Definition: jpeg_tool.c:228
JPEGImage read_jpeg_file(const char *fname)
Definition: jpeg_tool.c:31
JPEG TOOL HEADER.
unsigned char ** buf
Definition: jpeg_tool.h:96
unsigned char unsigned long * len
Definition: jpeg_tool.h:96
my_mem_destination_mgr * my_mem_dest_ptr
Definition: jpeg_tool.h:71
Definition: gdata.h:27
int zs
zサイズ. 4Byte. 2Dの場合は 1.
Definition: gdata.h:30
int xs
xサイズ. 4Byte.
Definition: gdata.h:28
int state
状態
Definition: gdata.h:31
uByte * gp
グラフィックデータへのポインタ. xs*ys*zs*1Byte.
Definition: gdata.h:32
int ys
yサイズ. 4Byte.
Definition: gdata.h:29
JSAMPLE * gp
Definition: jpeg_tool.h:53
int xs
Definition: jpeg_tool.h:49
int state
Definition: jpeg_tool.h:52
JSAMPARRAY img
Definition: jpeg_tool.h:54
int ys
Definition: jpeg_tool.h:50
int col
Definition: jpeg_tool.h:51
Definition: gdata.h:42
int zs
zサイズ. 4Byte. 2Dの場合は 1.
Definition: gdata.h:45
int xs
xサイズ. 4Byte.
Definition: gdata.h:43
int state
状態
Definition: gdata.h:46
sWord * gp
グラフィックデータへのポインタ. xs*ys*zs*2Byte.
Definition: gdata.h:47
int ys
yサイズ. 4Byte.
Definition: gdata.h:44
unsigned char ** outbuffer
Definition: jpeg_tool.h:64
struct jpeg_destination_mgr pub
Definition: jpeg_tool.h:62
unsigned long * outsize
Definition: jpeg_tool.h:65
unsigned char * newbuffer
Definition: jpeg_tool.h:66
#define freeNull(p)
Definition: tools.h:201