2 * This library is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published
4 * by the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This library is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 #include "bccmodels.h"
79 #define QUICKTIME_MARKER_SIZE 0x2c
80 #define AVI_MARKER_SIZE 0x12
81 #define QUICKTIME_JPEG_TAG 0x6d6a7067
82 #define QUICKTIME_AVI_TAG 0x41564931
85 METHODDEF(void) mjpeg_error_exit (j_common_ptr cinfo)
87 /* cinfo->err really points to a mjpeg_error_mgr struct, so coerce pointer */
88 mjpeg_error_ptr mjpegerr = (mjpeg_error_ptr) cinfo->err;
90 /* Always display the message. */
91 /* We could postpone this until after returning, if we chose. */
92 (*cinfo->err->output_message) (cinfo);
94 /* Return control to the setjmp point */
95 longjmp(mjpegerr->setjmp_buffer, 1);
100 struct jpeg_destination_mgr pub; /* public fields */
102 JOCTET *buffer; /* Pointer to buffer */
103 mjpeg_compressor *engine;
104 } mjpeg_destination_mgr;
106 typedef mjpeg_destination_mgr *mjpeg_dest_ptr;
110 * Initialize destination --- called by jpeg_start_compress
111 * before any data is actually written.
114 METHODDEF(void) init_destination(j_compress_ptr cinfo)
116 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
118 /* Set the pointer to the preallocated buffer */
119 if(!dest->engine->output_buffer)
121 dest->engine->output_buffer = new unsigned char[65536];
122 memset(dest->engine->output_buffer,0,65536);
123 dest->engine->output_allocated = 65536;
125 dest->buffer = dest->engine->output_buffer;
126 dest->pub.next_output_byte = dest->engine->output_buffer;
127 dest->pub.free_in_buffer = dest->engine->output_allocated;
131 * Empty the output buffer --- called whenever buffer fills up.
133 * In typical applications, this should write the entire output buffer
134 * (ignoring the current state of next_output_byte & free_in_buffer),
135 * reset the pointer & count to the start of the buffer, and return TRUE
136 * indicating that the buffer has been dumped.
138 * In applications that need to be able to suspend compression due to output
139 * overrun, a FALSE return indicates that the buffer cannot be emptied now.
140 * In this situation, the compressor will return to its caller (possibly with
141 * an indication that it has not accepted all the supplied scanlines). The
142 * application should resume compression after it has made more room in the
143 * output buffer. Note that there are substantial restrictions on the use of
144 * suspension --- see the documentation.
146 * When suspending, the compressor will back up to a convenient restart point
147 * (typically the start of the current MCU). next_output_byte & free_in_buffer
148 * indicate where the restart point will be if the current call returns FALSE.
149 * Data beyond this point will be regenerated after resumption, so do not
150 * write it out when emptying the buffer externally.
153 METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
155 /* Allocate a bigger buffer. */
156 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
158 dest->engine->output_size = dest->engine->output_allocated;
159 dest->engine->output_allocated *= 2;
160 unsigned char *new_buffer = new unsigned char[dest->engine->output_allocated];
161 memcpy(new_buffer, dest->engine->output_buffer, dest->engine->output_size);
162 delete [] dest->engine->output_buffer;
163 dest->engine->output_buffer = new_buffer;
164 dest->buffer = dest->engine->output_buffer;
165 dest->pub.next_output_byte = dest->buffer + dest->engine->output_size;
166 dest->pub.free_in_buffer = dest->engine->output_allocated - dest->engine->output_size;
172 * Terminate destination --- called by jpeg_finish_compress
173 * after all data has been written. Usually needs to flush buffer.
175 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
176 * application must deal with any cleanup that should happen even
179 METHODDEF(void) term_destination(j_compress_ptr cinfo)
181 /* Just get the length */
182 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
183 dest->engine->output_size = dest->engine->output_allocated - dest->pub.free_in_buffer;
186 GLOBAL(void) jpeg_buffer_dest(j_compress_ptr cinfo, mjpeg_compressor *engine)
190 /* The destination object is made permanent so that multiple JPEG images
191 * can be written to the same file without re-executing jpeg_stdio_dest.
192 * This makes it dangerous to use this manager and a different destination
193 * manager serially with the same JPEG object, because their private object
194 * sizes may be different. Caveat programmer.
196 if(cinfo->dest == NULL)
198 /* first time for this JPEG object? */
199 cinfo->dest = (struct jpeg_destination_mgr *)
200 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
202 sizeof(mjpeg_destination_mgr));
205 dest = (mjpeg_dest_ptr)cinfo->dest;
206 dest->pub.init_destination = init_destination;
207 dest->pub.empty_output_buffer = empty_output_buffer;
208 dest->pub.term_destination = term_destination;
209 dest->engine = engine;
226 struct jpeg_source_mgr pub; /* public fields */
228 JOCTET * buffer; /* start of buffer */
229 int bytes; /* total size of buffer */
232 typedef mjpeg_source_mgr* mjpeg_src_ptr;
234 METHODDEF(void) init_source(j_decompress_ptr cinfo)
236 //mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
239 METHODDEF(boolean) fill_input_buffer(j_decompress_ptr cinfo)
241 mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
243 src->buffer[0] = (JOCTET)0xFF;
244 src->buffer[1] = (JOCTET)M_EOI;
245 src->pub.next_input_byte = src->buffer;
246 src->pub.bytes_in_buffer = 2;
252 METHODDEF(void) skip_input_data(j_decompress_ptr cinfo, long num_bytes)
254 mjpeg_src_ptr src = (mjpeg_src_ptr)cinfo->src;
256 src->pub.next_input_byte += (size_t)num_bytes;
257 src->pub.bytes_in_buffer -= (size_t)num_bytes;
261 METHODDEF(void) term_source(j_decompress_ptr cinfo)
265 GLOBAL(void) jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long bytes)
269 /* first time for this JPEG object? */
270 if(cinfo->src == NULL)
272 cinfo->src = (struct jpeg_source_mgr*)
273 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
275 sizeof(mjpeg_source_mgr));
276 src = (mjpeg_src_ptr)cinfo->src;
279 src = (mjpeg_src_ptr)cinfo->src;
280 src->pub.init_source = init_source;
281 src->pub.fill_input_buffer = fill_input_buffer;
282 src->pub.skip_input_data = skip_input_data;
283 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
284 src->pub.term_source = term_source;
285 src->pub.bytes_in_buffer = bytes;
286 src->pub.next_input_byte = buffer;
287 src->buffer = buffer;
291 /* JPEG DHT Segment for YCrCb omitted from MJPEG data */
293 unsigned char jpeg_odml_dht[0x1a4] = {
294 0xff, 0xc4, 0x01, 0xa2,
296 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
299 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
302 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
303 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
304 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
305 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
306 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
307 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
308 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
309 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
310 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
311 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
312 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
315 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
316 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
317 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
318 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
319 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
320 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
321 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
322 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
323 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
324 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
325 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
331 * Parse the DHT table.
332 * This code comes from jpeg6b (jdmarker.c).
335 int jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
336 JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
338 unsigned int length = (dht[2] << 8) + dht[3] - 2;
339 unsigned int pos = 4;
340 unsigned int count, i;
344 unsigned char bits[17];
345 unsigned char huffval[256];
352 for (i = 1; i <= 16; ++i)
354 bits[i] = dht[pos++];
359 if (count > 256 || count > length)
362 for (i = 0; i < count; ++i)
363 huffval[i] = dht[pos++];
369 hufftbl = &ac_tables[index];
372 hufftbl = &dc_tables[index];
374 if (index < 0 || index >= NUM_HUFF_TBLS)
377 if (*hufftbl == NULL)
378 *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
379 if (*hufftbl == NULL)
382 memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
383 memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
406 static void reset_buffer(unsigned char **buffer, long *size, long *allocated)
411 static void delete_buffer(unsigned char **buffer, long *size, long *allocated)
421 static void append_buffer(unsigned char **buffer,
429 *buffer = new unsigned char[65536];
430 memset(*buffer,0,65536);
435 if(*size + data_size + 0x100 > *allocated)
437 *allocated = *size + data_size + 0x100;
438 unsigned char *new_buffer = new unsigned char[*allocated];
439 memcpy(new_buffer, *buffer, *size);
441 *buffer = new_buffer;
444 memcpy(*buffer + *size, data, data_size);
448 static void allocate_temps(mjpeg_t *mjpeg)
452 if(!mjpeg->temp_data)
454 switch(mjpeg->jpeg_color_model)
457 //printf("allocate_temps 1\n");
458 mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h * 2];
459 mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
460 mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h];
461 mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h];
462 for(i = 0; i < mjpeg->coded_h; i++)
464 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
465 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w / 2;
466 mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w / 2 * mjpeg->coded_h + i * mjpeg->coded_w / 2;
471 mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h * 3];
472 mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
473 mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h];
474 mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h];
477 memset(mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h,
479 mjpeg->coded_w * mjpeg->coded_h * 2);
481 for(i = 0; i < mjpeg->coded_h; i++)
483 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
484 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
485 mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
490 mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h / 2];
491 mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
492 mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h / 2];
493 mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h / 2];
494 for(i = 0; i < mjpeg->coded_h; i++)
496 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
497 if(i < mjpeg->coded_h / 2)
499 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * (mjpeg->coded_w / 2);
500 mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + (mjpeg->coded_h / 2) * (mjpeg->coded_w / 2) + i * (mjpeg->coded_w / 2);
508 static int get_input_row(mjpeg_t *mjpeg, mjpeg_compressor *compressor, int i)
511 if(mjpeg->fields > 1)
512 input_row = i * 2 + compressor->instance;
515 if(input_row >= mjpeg->coded_h) input_row = mjpeg->coded_h - 1;
519 // Get pointers to rows for the JPEG compressor
520 static void get_rows(mjpeg_t *mjpeg, mjpeg_compressor *compressor)
523 switch(mjpeg->jpeg_color_model)
527 if(!compressor->rows[0])
529 compressor->rows[0] = new unsigned char*[compressor->coded_field_h];
530 compressor->rows[1] = new unsigned char*[compressor->coded_field_h];
531 compressor->rows[2] = new unsigned char*[compressor->coded_field_h];
534 // User colormodel matches jpeg colormodel
535 if(mjpeg->color_model == BC_YUV444P &&
536 mjpeg->output_w == mjpeg->coded_w &&
537 mjpeg->output_h == mjpeg->coded_h)
539 for(i = 0; i < compressor->coded_field_h; i++)
541 int input_row = get_input_row(mjpeg, compressor, i);
542 compressor->rows[0][i] = mjpeg->y_argument +
543 mjpeg->coded_w * input_row;
544 compressor->rows[1][i] = mjpeg->u_argument +
545 mjpeg->coded_w * input_row;
546 compressor->rows[2][i] = mjpeg->v_argument +
547 mjpeg->coded_w * input_row;
552 for(i = 0; i < compressor->coded_field_h; i++)
554 int input_row = get_input_row(mjpeg, compressor, i);
555 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
556 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
557 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
565 if(!compressor->rows[0])
567 compressor->rows[0] = new unsigned char*[compressor->coded_field_h];
568 compressor->rows[1] = new unsigned char*[compressor->coded_field_h];
569 compressor->rows[2] = new unsigned char*[compressor->coded_field_h];
572 // User colormodel matches jpeg colormodel
573 if(mjpeg->color_model == BC_YUV422P &&
574 mjpeg->output_w == mjpeg->coded_w &&
575 mjpeg->output_h == mjpeg->coded_h)
577 for(i = 0; i < compressor->coded_field_h; i++)
579 int input_row = get_input_row(mjpeg, compressor, i);
580 compressor->rows[0][i] = mjpeg->y_argument +
581 mjpeg->coded_w * input_row;
582 compressor->rows[1][i] = mjpeg->u_argument +
583 (mjpeg->coded_w / 2) * input_row;
584 compressor->rows[2][i] = mjpeg->v_argument +
585 (mjpeg->coded_w / 2) * input_row;
590 for(i = 0; i < compressor->coded_field_h; i++)
592 int input_row = get_input_row(mjpeg, compressor, i);
593 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
594 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
595 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
603 if(!compressor->rows[0])
605 compressor->rows[0] = new unsigned char*[mjpeg->coded_h];
606 compressor->rows[1] = new unsigned char*[mjpeg->coded_h / 2];
607 compressor->rows[2] = new unsigned char*[mjpeg->coded_h / 2];
610 // User colormodel matches jpeg colormodel
611 if(mjpeg->color_model == BC_YUV420P &&
612 mjpeg->output_w == mjpeg->coded_w &&
613 mjpeg->output_h == mjpeg->coded_h)
615 for(i = 0; i < compressor->coded_field_h; i++)
617 int input_row = get_input_row(mjpeg, compressor, i);
618 compressor->rows[0][i] = mjpeg->y_argument +
619 mjpeg->coded_w * input_row;
620 if(i < compressor->coded_field_h / 2)
622 compressor->rows[1][i] = mjpeg->u_argument +
623 (mjpeg->coded_w / 2) * input_row;
624 compressor->rows[2][i] = mjpeg->v_argument +
625 (mjpeg->coded_w / 2) * input_row;
631 for(i = 0; i < compressor->coded_field_h; i++)
633 int input_row = get_input_row(mjpeg, compressor, i);
634 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
635 if(i < compressor->coded_field_h / 2)
637 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
638 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
647 static void delete_rows(mjpeg_compressor *compressor)
649 if(compressor->rows[0])
651 delete [] compressor->rows[0];
652 delete [] compressor->rows[1];
653 delete [] compressor->rows[2];
657 /* replacement routine to suppress decompress warnings */
658 static void mjpeg_emit_message(j_common_ptr cinfo, int msg_level)
660 struct jpeg_error_mgr * err = cinfo->err;
663 if(err->trace_level >= 3)
664 (*err->output_message) (cinfo);
666 if (err->trace_level >= msg_level)
667 (*err->output_message) (cinfo);
671 static void new_jpeg_objects(mjpeg_compressor *engine)
673 engine->jpeg_decompress.err = jpeg_std_error(&(engine->jpeg_error.pub));
674 engine->jpeg_error.pub.error_exit = mjpeg_error_exit;
675 engine->jpeg_error.pub.emit_message = mjpeg_emit_message;
676 /* Ideally the error handler would be set here but it must be called in a thread */
677 jpeg_create_decompress(&(engine->jpeg_decompress));
678 engine->jpeg_decompress.raw_data_out = TRUE;
679 #if JPEG_LIB_VERSION >= 70
680 engine->jpeg_decompress.do_fancy_upsampling = FALSE;
682 engine->jpeg_decompress.dct_method = JDCT_IFAST;
685 static void delete_jpeg_objects(mjpeg_compressor *engine)
687 jpeg_destroy_decompress(&(engine->jpeg_decompress));
692 static void unlock_compress_loop(mjpeg_compressor *engine)
694 pthread_mutex_unlock(&(engine->input_lock));
697 static void lock_compress_loop(mjpeg_compressor *engine)
699 pthread_mutex_lock(&(engine->output_lock));
702 // Make temp rows for compressor
703 static void get_mcu_rows(mjpeg_t *mjpeg,
704 mjpeg_compressor *engine,
707 int i, j, scanline, lastline;
708 for(i = 0; i < 3; i++)
710 for(j = 0; j < 16; j++)
712 scanline = start_row;
713 lastline = engine->coded_field_h;
714 if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) {
715 lastline /= 2; scanline /= 2;
718 if(scanline >= lastline) scanline = lastline - 1;
719 engine->mcu_rows[i][j] = engine->rows[i][scanline];
725 static void decompress_field(mjpeg_compressor *engine)
727 mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
728 long buffer_offset = engine->instance * mjpeg->input_field2;
729 unsigned char *buffer = mjpeg->input_data + buffer_offset;
732 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
733 if(engine->instance == 0 && mjpeg->fields > 1)
734 buffer_size = mjpeg->input_field2 - buffer_offset;
736 buffer_size = mjpeg->input_size - buffer_offset;
740 if(setjmp(engine->jpeg_error.setjmp_buffer))
742 /* If we get here, the JPEG code has signaled an error. */
743 printf("decompress_field %d\n", __LINE__);
744 delete_jpeg_objects(engine);
745 printf("decompress_field %d\n", __LINE__);
746 new_jpeg_objects(engine);
747 printf("decompress_field %d\n", __LINE__);
749 printf("decompress_field %d\n", __LINE__);
753 //printf("decompress_field 2\n");
754 jpeg_buffer_src(&engine->jpeg_decompress,
757 jpeg_read_header(&engine->jpeg_decompress, TRUE);
759 if ( engine->jpeg_decompress.ac_huff_tbl_ptrs[0] == NULL &&
760 engine->jpeg_decompress.ac_huff_tbl_ptrs[1] == NULL &&
761 engine->jpeg_decompress.dc_huff_tbl_ptrs[0] == NULL &&
762 engine->jpeg_decompress.dc_huff_tbl_ptrs[1] == NULL )
763 jpeg_load_dht( &engine->jpeg_decompress,
765 engine->jpeg_decompress.ac_huff_tbl_ptrs,
766 engine->jpeg_decompress.dc_huff_tbl_ptrs );
767 // Reset by jpeg_read_header
768 engine->jpeg_decompress.raw_data_out = TRUE;
769 #if JPEG_LIB_VERSION >= 70
770 engine->jpeg_decompress.do_fancy_upsampling = FALSE;
772 jpeg_start_decompress(&engine->jpeg_decompress);
774 // Generate colormodel from jpeg sampling
775 if( engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
776 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
777 mjpeg->jpeg_color_model = BC_YUV420P;
778 else if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 1 &&
779 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
780 mjpeg->jpeg_color_model = BC_YUV422P;
782 mjpeg->jpeg_color_model = BC_YUV444P;
784 if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE)
785 mjpeg->greyscale = 1;
787 //printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor);
788 // Must be here because the color model isn't known until now
789 pthread_mutex_lock(&(mjpeg->decompress_init));
790 allocate_temps(mjpeg);
791 pthread_mutex_unlock(&(mjpeg->decompress_init));
792 get_rows(mjpeg, engine);
794 //printf("decompress_field 30\n");
796 while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
798 get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
799 jpeg_read_raw_data(&engine->jpeg_decompress,
801 engine->coded_field_h);
803 jpeg_finish_decompress(&engine->jpeg_decompress);
805 //printf("decompress_field 40\n");
811 void mjpeg_decompress_loop(mjpeg_compressor *engine)
815 pthread_mutex_lock(&engine->input_lock);
818 decompress_field(engine);
820 pthread_mutex_unlock(&(engine->output_lock));
825 static void compress_field(mjpeg_compressor *engine)
827 mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
829 //printf("compress_field 1\n");
830 get_rows(mjpeg, engine);
831 reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
832 jpeg_buffer_dest(&engine->jpeg_compress, engine);
835 engine->jpeg_compress.raw_data_in = TRUE;
836 #if JPEG_LIB_VERSION >= 70
837 engine->jpeg_compress.do_fancy_downsampling = FALSE;
839 jpeg_start_compress(&engine->jpeg_compress, TRUE);
841 while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
843 get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
845 jpeg_write_raw_data(&engine->jpeg_compress,
847 engine->coded_field_h);
849 jpeg_finish_compress(&engine->jpeg_compress);
850 //printf("compress_field 2\n");
854 void mjpeg_compress_loop(mjpeg_compressor *engine)
858 pthread_mutex_lock(&engine->input_lock);
861 compress_field(engine);
863 pthread_mutex_unlock(&engine->output_lock);
867 static void delete_temps(mjpeg_t *mjpeg)
871 delete [] mjpeg->temp_data;
872 delete [] mjpeg->temp_rows[0];
873 delete [] mjpeg->temp_rows[1];
874 delete [] mjpeg->temp_rows[2];
875 mjpeg->temp_data = 0;
879 mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
881 mjpeg_compressor *result = new mjpeg_compressor();
882 memset(result, 0, sizeof(mjpeg_compressor));
884 pthread_mutexattr_t mutex_attr;
886 result->mjpeg = mjpeg;
887 result->instance = instance;
888 new_jpeg_objects(result);
889 result->field_h = mjpeg->output_h / mjpeg->fields;
890 result->coded_field_h = (result->field_h % 16) ?
891 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
893 result->mcu_rows[0] = new unsigned char *[16];
894 result->mcu_rows[1] = new unsigned char *[16];
895 result->mcu_rows[2] = new unsigned char *[16];
897 pthread_mutexattr_init(&mutex_attr);
898 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
899 pthread_mutex_init(&(result->input_lock), &mutex_attr);
900 pthread_mutex_lock(&(result->input_lock));
901 pthread_mutex_init(&(result->output_lock), &mutex_attr);
902 pthread_mutex_lock(&(result->output_lock));
904 pthread_attr_init(&attr);
905 pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_decompress_loop, result);
910 void mjpeg_delete_decompressor(mjpeg_compressor *engine)
913 pthread_mutex_unlock(&(engine->input_lock));
914 pthread_join(engine->tid, 0);
915 pthread_mutex_destroy(&(engine->input_lock));
916 pthread_mutex_destroy(&(engine->output_lock));
917 jpeg_destroy_decompress(&(engine->jpeg_decompress));
919 delete [] engine->mcu_rows[0];
920 delete [] engine->mcu_rows[1];
921 delete [] engine->mcu_rows[2];
925 mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
928 pthread_mutexattr_t mutex_attr;
929 mjpeg_compressor *result = new mjpeg_compressor();
930 memset(result, 0, sizeof(mjpeg_compressor));
932 result->field_h = mjpeg->output_h / mjpeg->fields;
933 result->coded_field_h = (result->field_h % 16) ?
934 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
935 result->mjpeg = mjpeg;
936 result->instance = instance;
937 result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
938 jpeg_create_compress(&(result->jpeg_compress));
939 result->jpeg_compress.image_width = mjpeg->output_w;
940 result->jpeg_compress.image_height = result->field_h;
941 result->jpeg_compress.input_components = 3;
942 result->jpeg_compress.in_color_space = JCS_RGB;
943 jpeg_set_defaults(&(result->jpeg_compress));
944 result->jpeg_compress.input_components = 3;
945 result->jpeg_compress.in_color_space = JCS_RGB;
946 jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
949 result->jpeg_compress.dct_method = JDCT_FLOAT;
951 result->jpeg_compress.dct_method = JDCT_IFAST;
952 // result->jpeg_compress.dct_method = JDCT_ISLOW;
955 switch(mjpeg->fields)
958 mjpeg->jpeg_color_model = BC_YUV420P;
959 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
960 result->jpeg_compress.comp_info[0].v_samp_factor = 2;
961 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
962 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
963 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
964 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
967 mjpeg->jpeg_color_model = BC_YUV422P;
968 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
969 result->jpeg_compress.comp_info[0].v_samp_factor = 1;
970 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
971 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
972 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
973 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
976 allocate_temps(mjpeg);
978 result->mcu_rows[0] = new unsigned char *[16];
979 result->mcu_rows[1] = new unsigned char *[16];
980 result->mcu_rows[2] = new unsigned char *[16];
982 pthread_mutexattr_init(&mutex_attr);
983 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
984 pthread_mutex_init(&(result->input_lock), &mutex_attr);
985 pthread_mutex_lock(&(result->input_lock));
986 pthread_mutex_init(&(result->output_lock), &mutex_attr);
987 pthread_mutex_lock(&(result->output_lock));
989 pthread_attr_init(&attr);
990 pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_compress_loop, result);
995 void mjpeg_delete_compressor(mjpeg_compressor *engine)
998 pthread_mutex_unlock(&(engine->input_lock));
999 pthread_join(engine->tid, 0);
1000 pthread_mutex_destroy(&(engine->input_lock));
1001 pthread_mutex_destroy(&(engine->output_lock));
1002 jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
1003 if(engine->output_buffer) delete [] engine->output_buffer;
1004 delete_rows(engine);
1005 delete [] engine->mcu_rows[0];
1006 delete [] engine->mcu_rows[1];
1007 delete [] engine->mcu_rows[2];
1011 unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
1013 return mjpeg->output_data;
1016 long mjpeg_output_field2(mjpeg_t *mjpeg)
1018 return mjpeg->output_field2;
1021 long mjpeg_output_size(mjpeg_t *mjpeg)
1023 return mjpeg->output_size;
1026 long mjpeg_output_allocated(mjpeg_t *mjpeg)
1028 return mjpeg->output_allocated;
1031 void mjpeg_set_output_size(mjpeg_t *mjpeg, long output_size)
1033 mjpeg->output_size = output_size;
1037 int mjpeg_compress(mjpeg_t *mjpeg,
1038 unsigned char **row_pointers,
1039 unsigned char *y_plane,
1040 unsigned char *u_plane,
1041 unsigned char *v_plane,
1046 int corrected_fields = mjpeg->fields;
1047 mjpeg->color_model = color_model;
1050 //printf("mjpeg_compress 1 %d\n", color_model);
1051 /* Reset output buffer */
1052 reset_buffer(&mjpeg->output_data,
1053 &mjpeg->output_size,
1054 &mjpeg->output_allocated);
1056 /* Create compression engines as needed */
1057 for(i = 0; i < mjpeg->fields; i++)
1059 if(!mjpeg->compressors[i])
1061 mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
1065 /* Arm YUV buffers */
1066 mjpeg->row_argument = row_pointers;
1067 mjpeg->y_argument = y_plane;
1068 mjpeg->u_argument = u_plane;
1069 mjpeg->v_argument = v_plane;
1070 // User colormodel doesn't match encoder colormodel
1071 // Copy to interlacing buffer first
1072 if(mjpeg->color_model != mjpeg->jpeg_color_model ||
1073 mjpeg->output_w != mjpeg->coded_w ||
1074 mjpeg->output_h != mjpeg->coded_h)
1077 * printf("mjpeg_compress %d %d %d %d\n",
1078 * mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_h);
1080 BC_CModels::transfer(0, row_pointers,
1081 mjpeg->temp_rows[0][0], mjpeg->temp_rows[1][0], mjpeg->temp_rows[2][0],
1082 y_plane, u_plane, v_plane,
1083 0, 0, mjpeg->output_w, mjpeg->output_h,
1084 0, 0, mjpeg->output_w, mjpeg->output_h,
1085 mjpeg->color_model, mjpeg->jpeg_color_model, 0,
1086 mjpeg->output_w, mjpeg->coded_w);
1089 /* Start the compressors on the image fields */
1090 if(mjpeg->deinterlace) corrected_fields = 1;
1091 for(i = 0; i < corrected_fields && !result; i++)
1093 unlock_compress_loop(mjpeg->compressors[i]);
1095 if(mjpeg->cpus < 2 && i < corrected_fields - 1)
1097 lock_compress_loop(mjpeg->compressors[i]);
1101 /* Wait for the compressors and store in master output */
1102 for(i = 0; i < corrected_fields && !result; i++)
1104 if(mjpeg->cpus > 1 || i == corrected_fields - 1)
1106 lock_compress_loop(mjpeg->compressors[i]);
1109 append_buffer(&mjpeg->output_data,
1110 &mjpeg->output_size,
1111 &mjpeg->output_allocated,
1112 mjpeg->compressors[i]->output_buffer,
1113 mjpeg->compressors[i]->output_size);
1114 if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
1117 if(corrected_fields < mjpeg->fields)
1119 append_buffer(&mjpeg->output_data,
1120 &mjpeg->output_size,
1121 &mjpeg->output_allocated,
1122 mjpeg->compressors[0]->output_buffer,
1123 mjpeg->compressors[0]->output_size);
1125 //printf("mjpeg_compress 2\n");
1131 int mjpeg_decompress(mjpeg_t *mjpeg,
1132 unsigned char *buffer,
1135 unsigned char **row_pointers,
1136 unsigned char *y_plane,
1137 unsigned char *u_plane,
1138 unsigned char *v_plane,
1143 int got_first_thread = 0;
1145 //printf("mjpeg_decompress 1 %d\n", color_model);
1146 if(buffer_len == 0) return 1;
1147 if(input_field2 == 0 && mjpeg->fields > 1) return 1;
1149 //printf("mjpeg_decompress 2\n");
1150 /* Create decompression engines as needed */
1151 for(i = 0; i < mjpeg->fields; i++)
1153 if(!mjpeg->decompressors[i])
1155 mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
1159 //printf("mjpeg_decompress 3\n");
1160 /* Arm YUV buffers */
1161 mjpeg->row_argument = row_pointers;
1162 mjpeg->y_argument = y_plane;
1163 mjpeg->u_argument = u_plane;
1164 mjpeg->v_argument = v_plane;
1165 mjpeg->input_data = buffer;
1166 mjpeg->input_size = buffer_len;
1167 mjpeg->input_field2 = input_field2;
1168 mjpeg->color_model = color_model;
1171 //printf("mjpeg_decompress 4 %02x %02x %d %02x %02x\n", buffer[0], buffer[1], input_field2, buffer[input_field2], buffer[input_field2 + 1]);
1172 /* Start decompressors */
1173 for(i = 0; i < mjpeg->fields && !result; i++)
1175 //printf("mjpeg_decompress 5\n");
1176 unlock_compress_loop(mjpeg->decompressors[i]);
1177 //printf("mjpeg_decompress 6\n");
1179 // For dual CPUs, don't want second thread to start until temp data is allocated by the first.
1180 // For single CPUs, don't want two threads running simultaneously
1181 if(mjpeg->cpus < 2 || !mjpeg->temp_data)
1183 //printf("mjpeg_decompress 7\n");
1184 lock_compress_loop(mjpeg->decompressors[i]);
1185 //printf("mjpeg_decompress 8\n");
1186 if(i == 0) got_first_thread = 1;
1190 //printf("mjpeg_decompress 10\n");
1191 /* Wait for decompressors */
1192 for(i = 0; i < mjpeg->fields && !result; i++)
1196 if(i > 0 || !got_first_thread)
1197 lock_compress_loop(mjpeg->decompressors[i]);
1201 /* Convert colormodel */
1202 // User colormodel didn't match decompressor
1204 * if(!mjpeg->error &&
1205 * (mjpeg->jpeg_color_model != mjpeg->color_model ||
1206 * mjpeg->coded_w != mjpeg->output_w ||
1207 * mjpeg->coded_h != mjpeg->output_h))
1210 //printf("mjpeg_decompress 6 %d %d %d %d\n", mjpeg->coded_w, mjpeg->coded_h, mjpeg->output_w, mjpeg->output_h);
1211 if((mjpeg->jpeg_color_model != mjpeg->color_model ||
1212 mjpeg->coded_w != mjpeg->output_w ||
1213 mjpeg->coded_h != mjpeg->output_h)
1215 (mjpeg->temp_data ||
1218 unsigned char *y_in = mjpeg->temp_rows[0][0];
1219 unsigned char *u_in = mjpeg->temp_rows[1][0];
1220 unsigned char *v_in = mjpeg->temp_rows[2][0];
1224 * printf("mjpeg_decompress 7 coded_w=%d coded_h=%d output_w=%d output_h=%d out_rowspan=%d in_colormodel=%d out_colormodel=%d\n",
1229 * mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w,
1230 * mjpeg->jpeg_color_model,
1231 * mjpeg->color_model);
1234 BC_CModels::transfer(row_pointers, 0,
1235 y_plane, u_plane, v_plane, y_in, u_in, v_in,
1236 0, 0, mjpeg->output_w, mjpeg->output_h,
1237 0, 0, mjpeg->output_w, mjpeg->output_h,
1238 mjpeg->jpeg_color_model, mjpeg->color_model, 0,
1239 mjpeg->coded_w, mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
1240 //printf("mjpeg_decompress 8\n");
1246 void mjpeg_set_deinterlace(mjpeg_t *mjpeg, int value)
1248 mjpeg->deinterlace = value;
1251 void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
1253 mjpeg->quality = quality;
1256 void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
1258 mjpeg->use_float = use_float;
1261 void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
1266 void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan)
1268 mjpeg->rowspan = rowspan;
1271 int mjpeg_get_fields(mjpeg_t *mjpeg)
1273 return mjpeg->fields;
1277 mjpeg_t* mjpeg_new(int w,
1281 mjpeg_t *result = new mjpeg_t();
1282 memset(result, 0, sizeof(*result));
1283 pthread_mutexattr_t mutex_attr;
1285 result->output_w = w;
1286 result->output_h = h;
1287 result->fields = fields;
1288 result->color_model = BC_RGB888;
1290 result->quality = 80;
1291 result->use_float = 0;
1293 pthread_mutexattr_init(&mutex_attr);
1294 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1295 pthread_mutex_init(&(result->decompress_init), &mutex_attr);
1298 // Calculate coded dimensions
1299 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1301 result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
1304 result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
1306 result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
1310 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1317 void mjpeg_delete(mjpeg_t *mjpeg)
1320 //printf("mjpeg_delete 1\n");
1321 for(i = 0; i < mjpeg->fields; i++)
1323 //printf("mjpeg_delete 2\n");
1324 if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
1325 //printf("mjpeg_delete 3\n");
1326 if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
1327 //printf("mjpeg_delete 4\n");
1329 //printf("mjpeg_delete 5\n");
1330 delete_temps(mjpeg);
1331 //printf("mjpeg_delete 6\n");
1332 delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
1333 //printf("mjpeg_delete 7\n");
1335 //printf("mjpeg_delete 2\n");
1339 /* Open up a space to insert a marker */
1340 static void insert_space(unsigned char **buffer,
1342 long *buffer_allocated,
1347 // Make sure enough space is available
1348 if(*buffer_allocated - *buffer_size < space_len)
1350 *buffer_allocated += space_len;
1351 unsigned char *new_buffer = new unsigned char[*buffer_allocated];
1352 memcpy(new_buffer, *buffer, *buffer_size);
1354 *buffer = new_buffer;
1358 for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
1362 (*buffer)[out] = (*buffer)[in];
1364 *buffer_size += space_len;
1368 static inline int nextbyte(unsigned char *data, long *offset, long length)
1370 if(length - *offset < 1) return 0;
1372 return (unsigned char)data[*offset - 1];
1375 static inline int read_int32(unsigned char *data, long *offset, long length)
1377 if(length - *offset < 4)
1383 return ((((unsigned int)data[*offset - 4]) << 24) |
1384 (((unsigned int)data[*offset - 3]) << 16) |
1385 (((unsigned int)data[*offset - 2]) << 8) |
1386 (((unsigned int)data[*offset - 1])));
1389 static inline int read_int16(unsigned char *data, long *offset, long length)
1391 if(length - *offset < 2)
1398 return ((((unsigned int)data[*offset - 2]) << 8) |
1399 (((unsigned int)data[*offset - 1])));
1402 static inline unsigned char read_char(unsigned char *data, long *offset, long length)
1404 if(length - *offset < 1)
1411 return (unsigned char)data[*offset - 1];
1414 static inline int next_int16(unsigned char *data, long *offset, long length)
1416 if(length - *offset < 2)
1421 return ((((unsigned int)data[*offset]) << 8) |
1422 (((unsigned int)data[*offset + 1])));
1425 static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
1427 if(length - *offset < 4)
1434 data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
1435 data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
1436 data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
1437 data[(*offset)++] = (unsigned char)(value & 0xff);
1441 static inline void write_char(unsigned char *data, long *offset, long length, unsigned char value)
1443 if(length - *offset < 1)
1449 data[(*offset)++] = value;
1453 static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
1455 while(*offset < buffer_size - 1) {
1456 if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff) {
1458 return buffer[*offset - 1];
1465 /* Find the next marker after offset and return 0 on success */
1466 static int find_marker(unsigned char *buffer,
1469 unsigned long marker_type)
1473 while(!result && *offset < buffer_size - 1)
1475 unsigned int marker = next_marker(buffer, offset, buffer_size);
1476 if(marker == (marker_type & 0xff)) result = 1;
1486 int padded_field_size;
1499 int unpadded_field_size;
1503 static int qt_table_offsets(unsigned char *buffer,
1514 bzero(header, sizeof(qt_hdr_t) * 2);
1516 // Read every marker to get the offsets for the headers
1517 for(field = 0; field < 2; field++)
1523 marker = next_marker(buffer,
1532 // The first field may be padded
1535 header[0].next_offset =
1536 header[0].padded_field_size =
1543 // Quicktime marker already exists. Abort.
1544 if(buffer[offset + 6] == 'm' &&
1545 buffer[offset + 7] == 'j' &&
1546 buffer[offset + 8] == 'p' &&
1547 buffer[offset + 9] == 'a')
1555 if(!header[field].quant_offset)
1557 header[field].quant_offset = offset - 2;
1559 header[field].quant_offset -= header[0].next_offset;
1561 len = read_int16(buffer, &offset, buffer_size);
1566 if(!header[field].huffman_offset)
1568 header[field].huffman_offset = offset - 2;
1570 header[field].huffman_offset -= header[0].next_offset;
1572 len = read_int16(buffer, &offset, buffer_size);
1577 if(!header[field].image_offset)
1579 header[field].image_offset = offset - 2;
1581 header[field].image_offset -= header[0].next_offset;
1583 len = read_int16(buffer, &offset, buffer_size);
1588 header[field].scan_offset = offset - 2;
1590 header[field].scan_offset -= header[0].next_offset;
1591 len = read_int16(buffer, &offset, buffer_size);
1593 header[field].data_offset = offset + len;
1595 header[field].data_offset -= header[0].next_offset;
1602 header[field].field_size =
1603 header[field].padded_field_size =
1604 offset - header[0].next_offset;
1605 header[field].next_offset = 0;
1609 // Often misses second SOI but gets first EOI
1610 // header[0].next_offset =
1611 // header[0].padded_field_size =
1614 //printf("table_offsets M_EOI %d %x\n", field, offset);
1620 // Junk appears between fields
1622 // len = read_int16(buffer, &offset, buffer_size);
1627 if(!done) offset += len;
1628 if(offset >= buffer_size) done = 1;
1630 //printf("qt_table_offsets 10 %d\n", field);
1636 static void insert_quicktime_marker(unsigned char *buffer,
1641 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1642 ((unsigned long)M_APP1 << 16) |
1643 (QUICKTIME_MARKER_SIZE - 2));
1644 write_int32(buffer, &offset, buffer_size, 0);
1645 write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1646 write_int32(buffer, &offset, buffer_size, header->field_size);
1647 write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1648 write_int32(buffer, &offset, buffer_size, header->next_offset);
1649 write_int32(buffer, &offset, buffer_size, header->quant_offset);
1650 write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1651 write_int32(buffer, &offset, buffer_size, header->image_offset);
1652 write_int32(buffer, &offset, buffer_size, header->scan_offset);
1653 write_int32(buffer, &offset, buffer_size, header->data_offset);
1657 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1659 long *buffer_allocated,
1661 long *field2_offset)
1665 *field2_offset = -1;
1667 if(fields < 2) return;
1670 // Get offsets for tables in both fields
1671 exists = qt_table_offsets(*buffer, *buffer_size, header);
1673 // APP1 for quicktime already exists
1676 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1677 // header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1678 //if(*field2_offset == 0)
1679 // fwrite(*buffer, *buffer_size, 1, stdout);
1683 header[0].field_size += QUICKTIME_MARKER_SIZE;
1684 header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1685 header[0].next_offset += QUICKTIME_MARKER_SIZE;
1686 header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1687 header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1688 header[0].image_offset += QUICKTIME_MARKER_SIZE;
1689 header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1690 header[0].data_offset += QUICKTIME_MARKER_SIZE;
1691 header[1].field_size += QUICKTIME_MARKER_SIZE;
1692 header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1693 header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1694 header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1695 header[1].image_offset += QUICKTIME_MARKER_SIZE;
1696 header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1697 header[1].data_offset += QUICKTIME_MARKER_SIZE;
1698 *field2_offset = header[0].next_offset;
1702 // Insert APP1 marker
1703 insert_space(buffer,
1707 QUICKTIME_MARKER_SIZE);
1709 insert_quicktime_marker(*buffer,
1714 insert_space(buffer,
1717 header[0].next_offset + 2,
1718 QUICKTIME_MARKER_SIZE);
1720 header[1].next_offset = 0;
1721 insert_quicktime_marker(*buffer,
1723 header[0].next_offset + 2,
1728 static int avi_table_offsets(unsigned char *buffer,
1732 int field2 = mjpeg_get_field2(buffer, buffer_size);
1734 header[0].field_number = 1;
1735 header[0].field_size = field2;
1736 header[0].unpadded_field_size = field2;
1738 header[1].field_number = 2;
1739 header[1].field_size = buffer_size - field2;
1740 header[1].unpadded_field_size = buffer_size - field2;
1744 static void insert_avi_marker(unsigned char *buffer,
1749 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1750 ((unsigned long)M_APP0 << 16) |
1751 (AVI_MARKER_SIZE - 2));
1752 write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1754 // One version of McRoweSoft only allows field polarity while
1755 // another version allows field size.
1756 write_char(buffer, &offset, buffer_size, header->field_number);
1757 write_char(buffer, &offset, buffer_size, 0);
1758 write_int32(buffer, &offset, buffer_size, header->field_size);
1759 write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1762 void mjpeg_insert_avi_markers(unsigned char **buffer,
1764 long *buffer_allocated,
1766 long *field2_offset)
1768 avi_hdr_t header[2];
1770 *field2_offset = -1;
1773 // Test for existing marker
1774 if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1776 if((*buffer)[offset + 2] == 'A' &&
1777 (*buffer)[offset + 3] == 'V' &&
1778 (*buffer)[offset + 4] == 'I' &&
1779 (*buffer)[offset + 5] == '1')
1784 avi_table_offsets(*buffer, *buffer_size, header);
1786 header[0].field_size += AVI_MARKER_SIZE;
1787 header[0].unpadded_field_size += AVI_MARKER_SIZE;
1788 header[1].field_size += AVI_MARKER_SIZE;
1789 header[1].unpadded_field_size += AVI_MARKER_SIZE;
1790 *field2_offset = header[0].field_size;
1792 // Insert APP0 marker into field 1
1793 insert_space(buffer,
1798 insert_avi_marker(*buffer,
1803 insert_space(buffer,
1808 insert_avi_marker(*buffer,
1818 static void read_avi_markers(unsigned char *buffer,
1823 int marker_count = 0;
1825 int marker_size = 0;
1826 while(marker_count < 2 && offset < buffer_size && !result)
1828 result = find_marker(buffer,
1832 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1835 if(!result && marker_size >= 16)
1837 // Marker size, AVI1
1840 header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1841 read_char(buffer, &offset, buffer_size);
1842 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1843 header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1850 static void read_quicktime_markers(unsigned char *buffer,
1855 int marker_count = 0;
1858 while(marker_count < 2 && offset < buffer_size && !result)
1860 result = find_marker(buffer,
1868 read_int16(buffer, &offset, buffer_size);
1870 read_int32(buffer, &offset, buffer_size);
1872 read_int32(buffer, &offset, buffer_size);
1874 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1875 header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1876 header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1877 header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1878 header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1879 header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1880 header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1881 header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1885 //printf("read_quicktime_markers 1 %d\n", marker_count);
1888 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1891 bzero(&header, sizeof(qt_hdr_t) * 2);
1893 read_quicktime_markers(buffer, buffer_size, header);
1894 return header[0].next_offset;
1897 long mjpeg_get_avi_field2(unsigned char *buffer,
1899 int *field_dominance)
1901 avi_hdr_t header[2];
1902 bzero(&header, sizeof(avi_hdr_t) * 2);
1903 read_avi_markers(buffer, buffer_size, header);
1905 *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1907 // One version of McRoweSoft only allows field polarity while
1908 // another version allows field size.
1909 if(header[0].field_size)
1911 return header[0].field_size;
1915 return mjpeg_get_field2(buffer, buffer_size);
1920 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1922 int total_fields = 0;
1923 long field2_offset = 0;
1926 for(i = 0; i < buffer_size; i++)
1928 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1932 if(total_fields == 2) break;
1935 return field2_offset;
1938 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1945 *h = (data[offset + 3] << 8) | (data[offset + 4]);
1946 *w = (data[offset + 5] << 8) | (data[offset + 6]);