2 #include <lib/picviewer/format_config.h>
3 #ifdef FBV_SUPPORT_JPEG
4 #include <lib/picviewer/pictureviewer.h>
12 struct r_jpeg_error_mgr
14 struct jpeg_error_mgr pub
;
18 int fh_jpeg_id(const char *name
)
20 // dbout("fh_jpeg_id {\n");
23 fd
= open(name
,O_RDONLY
);
28 // dbout("fh_jpeg_id }\n");
29 if (id
[6] == 'J' && id
[7] == 'F' && id
[8] == 'I' && id
[9] == 'F')
31 if (id
[0] == 0xff && id
[1] == 0xd8 && id
[2] == 0xff)
36 void jpeg_cb_error_exit(j_common_ptr cinfo
)
38 // dbout("jpeg_cd_error_exit {\n");
39 struct r_jpeg_error_mgr
*mptr
;
40 mptr
= (struct r_jpeg_error_mgr
*) cinfo
->err
;
41 (*cinfo
->err
->output_message
) (cinfo
);
42 longjmp(mptr
->envbuffer
, 1);
43 // dbout("jpeg_cd_error_exit }\n");
46 int fh_jpeg_load(const char *filename
, unsigned char *buffer
, int x
, int y
)
48 // dbout("fh_jpeg_load (%d/%d) {\n",x,y);
49 struct jpeg_decompress_struct cinfo
;
50 struct jpeg_decompress_struct
*ciptr
;
51 struct r_jpeg_error_mgr emgr
;
58 if (!(fh
= fopen(filename
, "rb")))
59 return(FH_ERROR_FILE
);
60 ciptr
->err
= jpeg_std_error(&emgr
.pub
);
61 emgr
.pub
.error_exit
= jpeg_cb_error_exit
;
62 if (setjmp(emgr
.envbuffer
) == 1)
64 // FATAL ERROR - Free the object and return...
65 jpeg_destroy_decompress(ciptr
);
67 // dbout("fh_jpeg_load } - FATAL ERROR\n");
68 return(FH_ERROR_FORMAT
);
71 jpeg_create_decompress(ciptr
);
72 jpeg_stdio_src(ciptr
, fh
);
73 jpeg_read_header(ciptr
, TRUE
);
74 ciptr
->out_color_space
= JCS_RGB
;
75 if (x
== (int)ciptr
->image_width
)
76 ciptr
->scale_denom
= 1;
78 if (abs(x
* 2 - ciptr
->image_width
) < 2)
79 ciptr
->scale_denom
= 2;
81 if (abs(x
* 4 - ciptr
->image_width
) < 4)
82 ciptr
->scale_denom
= 4;
84 if (abs(x
* 8 - ciptr
->image_width
) < 8)
85 ciptr
->scale_denom
= 8;
87 ciptr
->scale_denom
= 1;
89 jpeg_start_decompress(ciptr
);
91 px
= ciptr
->output_width
; py
= ciptr
->output_height
;
92 c
= ciptr
->output_components
;
96 lb
= (JSAMPLE
*)(*ciptr
->mem
->alloc_small
)((j_common_ptr
) ciptr
, JPOOL_PERMANENT
, c
* px
);
98 while (ciptr
->output_scanline
< ciptr
->output_height
)
100 jpeg_read_scanlines(ciptr
, &lb
, 1);
101 memcpy(bp
, lb
, px
* c
);
105 jpeg_finish_decompress(ciptr
);
106 jpeg_destroy_decompress(ciptr
);
108 // dbout("fh_jpeg_load }\n");
112 int fh_jpeg_save (JSAMPLE
* image_buffer
, char * filename
, int quality
, int image_height
, int image_width
)
114 struct jpeg_compress_struct cinfo
;
115 struct jpeg_error_mgr jerr
;
116 FILE * outfile
; /* target file */
117 JSAMPROW row_pointer
[1];/* pointer to JSAMPLE row[s] */
118 int row_stride
; /* physical row width in image buffer */
120 cinfo
.err
= jpeg_std_error(&jerr
);
121 jpeg_create_compress(&cinfo
);
123 if ((outfile
= fopen(filename
, "wb")) == NULL
)
125 eDebug("can't open %s", filename
);
128 jpeg_stdio_dest(&cinfo
, outfile
);
130 cinfo
.image_width
= image_width
; /* image width and height, in pixels */
131 cinfo
.image_height
= image_height
;
132 cinfo
.input_components
= 3; /* # of color components per pixel */
133 cinfo
.in_color_space
= JCS_RGB
; /* colorspace of input image */
135 jpeg_set_defaults(&cinfo
);
136 jpeg_set_quality(&cinfo
, quality
, TRUE
/* limit to baseline-JPEG values */);
137 jpeg_start_compress(&cinfo
, TRUE
);
138 row_stride
= image_width
* 3; /* JSAMPLEs per row in image_buffer */
139 while (cinfo
.next_scanline
< cinfo
.image_height
)
141 row_pointer
[0] = & image_buffer
[cinfo
.next_scanline
* row_stride
];
142 (void) jpeg_write_scanlines(&cinfo
, row_pointer
, 1);
144 jpeg_finish_compress(&cinfo
);
146 jpeg_destroy_compress(&cinfo
);
150 int fh_jpeg_getsize(const char *filename
, int *x
, int *y
, int wanted_width
, int wanted_height
)
152 // dbout("fh_jpeg_getsize {\n");
153 struct jpeg_decompress_struct cinfo
;
154 struct jpeg_decompress_struct
*ciptr
;
155 struct r_jpeg_error_mgr emgr
;
161 if (!(fh
= fopen(filename
, "rb")))
162 return(FH_ERROR_FILE
);
164 ciptr
->err
= jpeg_std_error(&emgr
.pub
);
165 emgr
.pub
.error_exit
= jpeg_cb_error_exit
;
166 if (setjmp(emgr
.envbuffer
) == 1)
168 // FATAL ERROR - Free the object and return...
169 jpeg_destroy_decompress(ciptr
);
171 // dbout("fh_jpeg_getsize } - FATAL ERROR\n");
172 return(FH_ERROR_FORMAT
);
175 jpeg_create_decompress(ciptr
);
176 jpeg_stdio_src(ciptr
, fh
);
177 jpeg_read_header(ciptr
, TRUE
);
178 ciptr
->out_color_space
= JCS_RGB
;
179 // should be more flexible...
180 if ((int)ciptr
->image_width
/ 8 >= wanted_width
|| (int)ciptr
->image_height
/ 8 >= wanted_height
)
181 ciptr
->scale_denom
= 8;
183 if ((int)ciptr
->image_width
/ 4 >= wanted_width
|| (int)ciptr
->image_height
/ 4 >= wanted_height
)
184 ciptr
->scale_denom
= 4;
186 if ((int)ciptr
->image_width
/ 2 >= wanted_width
|| (int)ciptr
->image_height
/ 2 >= wanted_height
)
187 ciptr
->scale_denom
= 2;
189 ciptr
->scale_denom
= 1;
191 jpeg_start_decompress(ciptr
);
192 px
= ciptr
->output_width
; py
= ciptr
->output_height
;
193 c
= ciptr
->output_components
;
195 // jpeg_finish_decompress(ciptr);
196 jpeg_destroy_decompress(ciptr
);
198 // dbout("fh_jpeg_getsize }\n");