54 struct jpeg_destination_mgr pub;
56 std::ostream * outfile;
60 typedef my_destination_mgr * my_dest_ptr;
62 #define OUTPUT_BUF_SIZE 4096
71 init_destination (j_compress_ptr cinfo)
73 my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
76 dest->buffer = (JOCTET *)
77 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
78 OUTPUT_BUF_SIZE *
sizeof(JOCTET));
80 dest->pub.next_output_byte = dest->buffer;
81 dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
109 empty_output_buffer (j_compress_ptr cinfo)
111 my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
113 if (!dest->outfile->write((
const char *)dest->buffer, OUTPUT_BUF_SIZE))
114 ERREXIT(cinfo, JERR_FILE_WRITE);
116 dest->pub.next_output_byte = dest->buffer;
117 dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
134 term_destination (j_compress_ptr cinfo)
136 my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
137 size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
141 if (!dest->outfile->write((
const char *)dest->buffer, datacount))
142 ERREXIT(cinfo, JERR_FILE_WRITE);
144 dest->outfile->flush();
147 if (dest->outfile->fail())
148 ERREXIT(cinfo, JERR_FILE_WRITE);
159 jpeg_ostream_dest (j_compress_ptr cinfo, std::ostream * outfile)
169 if (cinfo->dest ==
nullptr) {
170 cinfo->dest = (
struct jpeg_destination_mgr *)
171 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
172 sizeof(my_destination_mgr));
175 dest = (my_dest_ptr) cinfo->dest;
176 dest->pub.init_destination = init_destination;
177 dest->pub.empty_output_buffer = empty_output_buffer;
178 dest->pub.term_destination = term_destination;
179 dest->outfile = outfile;
189 PNMFileTypeJPG::Writer::
190 Writer(
PNMFileType *type, std::ostream *file,
bool owns_file) :
211 int PNMFileTypeJPG::Writer::
212 write_data(
xel *array, xelval *) {
213 if (_y_size<=0 || _x_size<=0) {
223 struct jpeg_compress_struct cinfo;
232 struct jpeg_error_mgr jerr;
234 JSAMPROW row_pointer[1];
244 cinfo.err = jpeg_std_error(&jerr);
247 jpeg_create_compress(&cinfo);
251 jpeg_ostream_dest(&cinfo, _file);
258 cinfo.image_width = _x_size;
259 cinfo.image_height = _y_size;
260 if (is_grayscale()) {
261 cinfo.input_components = 1;
262 cinfo.in_color_space = JCS_GRAYSCALE;
264 cinfo.input_components = 3;
265 cinfo.in_color_space = JCS_RGB;
271 jpeg_set_defaults(&cinfo);
275 jpeg_set_quality(&cinfo, jpeg_quality, TRUE );
282 jpeg_start_compress(&cinfo, TRUE);
285 if (_comment.size()) {
287 &cinfo, JPEG_COM, (JOCTET *)_comment.c_str(), strlen(_comment.c_str()));
298 row_stride = _x_size * cinfo.input_components;
301 JSAMPROW row =
new JSAMPLE[row_stride];
302 while (cinfo.next_scanline < cinfo.image_height) {
307 for (
int i = 0; i < row_stride; i += cinfo.input_components) {
308 if (cinfo.input_components == 1) {
309 row[i] = (JSAMPLE)(MAXJSAMPLE * PPM_GETB(array[x])/_maxval);
311 row[i] = (JSAMPLE)(MAXJSAMPLE * PPM_GETR(array[x])/_maxval);
312 row[i+1] = (JSAMPLE)(MAXJSAMPLE * PPM_GETG(array[x])/_maxval);
313 row[i+2] = (JSAMPLE)(MAXJSAMPLE * PPM_GETB(array[x])/_maxval);
319 row_pointer[0] = row;
320 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
326 jpeg_finish_compress(&cinfo);
331 jpeg_destroy_compress(&cinfo);