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,
708 for(i = 0; i < 3; i++)
710 for(j = 0; j < 16; j++)
712 if(i > 0 && j >= 8 && mjpeg->jpeg_color_model == BC_YUV420P) break;
714 scanline = start_row;
715 if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) scanline /= 2;
717 if(scanline >= engine->coded_field_h) scanline = engine->coded_field_h - 1;
718 engine->mcu_rows[i][j] = engine->rows[i][scanline];
724 static void decompress_field(mjpeg_compressor *engine)
726 mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
727 long buffer_offset = engine->instance * mjpeg->input_field2;
728 unsigned char *buffer = mjpeg->input_data + buffer_offset;
731 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
732 if(engine->instance == 0 && mjpeg->fields > 1)
733 buffer_size = mjpeg->input_field2 - buffer_offset;
735 buffer_size = mjpeg->input_size - buffer_offset;
739 if(setjmp(engine->jpeg_error.setjmp_buffer))
741 /* If we get here, the JPEG code has signaled an error. */
742 printf("decompress_field %d\n", __LINE__);
743 delete_jpeg_objects(engine);
744 printf("decompress_field %d\n", __LINE__);
745 new_jpeg_objects(engine);
746 printf("decompress_field %d\n", __LINE__);
748 printf("decompress_field %d\n", __LINE__);
752 //printf("decompress_field 2\n");
753 jpeg_buffer_src(&engine->jpeg_decompress,
756 jpeg_read_header(&engine->jpeg_decompress, TRUE);
758 if ( engine->jpeg_decompress.ac_huff_tbl_ptrs[0] == NULL &&
759 engine->jpeg_decompress.ac_huff_tbl_ptrs[1] == NULL &&
760 engine->jpeg_decompress.dc_huff_tbl_ptrs[0] == NULL &&
761 engine->jpeg_decompress.dc_huff_tbl_ptrs[1] == NULL )
762 jpeg_load_dht( &engine->jpeg_decompress,
764 engine->jpeg_decompress.ac_huff_tbl_ptrs,
765 engine->jpeg_decompress.dc_huff_tbl_ptrs );
766 // Reset by jpeg_read_header
767 engine->jpeg_decompress.raw_data_out = TRUE;
768 #if JPEG_LIB_VERSION >= 70
769 engine->jpeg_decompress.do_fancy_upsampling = FALSE;
771 jpeg_start_decompress(&engine->jpeg_decompress);
773 // Generate colormodel from jpeg sampling
774 if( engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
775 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
776 mjpeg->jpeg_color_model = BC_YUV420P;
777 else if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 1 &&
778 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
779 mjpeg->jpeg_color_model = BC_YUV422P;
781 mjpeg->jpeg_color_model = BC_YUV444P;
783 if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE)
784 mjpeg->greyscale = 1;
786 //printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor);
787 // Must be here because the color model isn't known until now
788 pthread_mutex_lock(&(mjpeg->decompress_init));
789 allocate_temps(mjpeg);
790 pthread_mutex_unlock(&(mjpeg->decompress_init));
791 get_rows(mjpeg, engine);
793 //printf("decompress_field 30\n");
795 while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
797 get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
798 jpeg_read_raw_data(&engine->jpeg_decompress,
800 engine->coded_field_h);
802 jpeg_finish_decompress(&engine->jpeg_decompress);
804 //printf("decompress_field 40\n");
810 void mjpeg_decompress_loop(mjpeg_compressor *engine)
814 pthread_mutex_lock(&engine->input_lock);
817 decompress_field(engine);
819 pthread_mutex_unlock(&(engine->output_lock));
824 static void compress_field(mjpeg_compressor *engine)
826 mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
828 //printf("compress_field 1\n");
829 get_rows(mjpeg, engine);
830 reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
831 jpeg_buffer_dest(&engine->jpeg_compress, engine);
834 engine->jpeg_compress.raw_data_in = TRUE;
835 #if JPEG_LIB_VERSION >= 70
836 engine->jpeg_compress.do_fancy_downsampling = FALSE;
838 jpeg_start_compress(&engine->jpeg_compress, TRUE);
840 while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
842 get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
844 jpeg_write_raw_data(&engine->jpeg_compress,
846 engine->coded_field_h);
848 jpeg_finish_compress(&engine->jpeg_compress);
849 //printf("compress_field 2\n");
853 void mjpeg_compress_loop(mjpeg_compressor *engine)
857 pthread_mutex_lock(&engine->input_lock);
860 compress_field(engine);
862 pthread_mutex_unlock(&engine->output_lock);
866 static void delete_temps(mjpeg_t *mjpeg)
870 delete [] mjpeg->temp_data;
871 delete [] mjpeg->temp_rows[0];
872 delete [] mjpeg->temp_rows[1];
873 delete [] mjpeg->temp_rows[2];
874 mjpeg->temp_data = 0;
878 mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
880 mjpeg_compressor *result = new mjpeg_compressor();
881 memset(result, 0, sizeof(mjpeg_compressor));
883 pthread_mutexattr_t mutex_attr;
885 result->mjpeg = mjpeg;
886 result->instance = instance;
887 new_jpeg_objects(result);
888 result->field_h = mjpeg->output_h / mjpeg->fields;
889 result->coded_field_h = (result->field_h % 16) ?
890 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
892 result->mcu_rows[0] = new unsigned char *[16];
893 result->mcu_rows[1] = new unsigned char *[16];
894 result->mcu_rows[2] = new unsigned char *[16];
896 pthread_mutexattr_init(&mutex_attr);
897 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
898 pthread_mutex_init(&(result->input_lock), &mutex_attr);
899 pthread_mutex_lock(&(result->input_lock));
900 pthread_mutex_init(&(result->output_lock), &mutex_attr);
901 pthread_mutex_lock(&(result->output_lock));
903 pthread_attr_init(&attr);
904 pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_decompress_loop, result);
909 void mjpeg_delete_decompressor(mjpeg_compressor *engine)
912 pthread_mutex_unlock(&(engine->input_lock));
913 pthread_join(engine->tid, 0);
914 pthread_mutex_destroy(&(engine->input_lock));
915 pthread_mutex_destroy(&(engine->output_lock));
916 jpeg_destroy_decompress(&(engine->jpeg_decompress));
918 delete [] engine->mcu_rows[0];
919 delete [] engine->mcu_rows[1];
920 delete [] engine->mcu_rows[2];
924 mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
927 pthread_mutexattr_t mutex_attr;
928 mjpeg_compressor *result = new mjpeg_compressor();
929 memset(result, 0, sizeof(mjpeg_compressor));
931 result->field_h = mjpeg->output_h / mjpeg->fields;
932 result->coded_field_h = (result->field_h % 16) ?
933 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
934 result->mjpeg = mjpeg;
935 result->instance = instance;
936 result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
937 jpeg_create_compress(&(result->jpeg_compress));
938 result->jpeg_compress.image_width = mjpeg->output_w;
939 result->jpeg_compress.image_height = result->field_h;
940 result->jpeg_compress.input_components = 3;
941 result->jpeg_compress.in_color_space = JCS_RGB;
942 jpeg_set_defaults(&(result->jpeg_compress));
943 result->jpeg_compress.input_components = 3;
944 result->jpeg_compress.in_color_space = JCS_RGB;
945 jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
948 result->jpeg_compress.dct_method = JDCT_FLOAT;
950 result->jpeg_compress.dct_method = JDCT_IFAST;
951 // result->jpeg_compress.dct_method = JDCT_ISLOW;
954 switch(mjpeg->fields)
957 mjpeg->jpeg_color_model = BC_YUV420P;
958 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
959 result->jpeg_compress.comp_info[0].v_samp_factor = 2;
960 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
961 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
962 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
963 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
966 mjpeg->jpeg_color_model = BC_YUV422P;
967 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
968 result->jpeg_compress.comp_info[0].v_samp_factor = 1;
969 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
970 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
971 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
972 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
975 allocate_temps(mjpeg);
977 result->mcu_rows[0] = new unsigned char *[16];
978 result->mcu_rows[1] = new unsigned char *[16];
979 result->mcu_rows[2] = new unsigned char *[16];
981 pthread_mutexattr_init(&mutex_attr);
982 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
983 pthread_mutex_init(&(result->input_lock), &mutex_attr);
984 pthread_mutex_lock(&(result->input_lock));
985 pthread_mutex_init(&(result->output_lock), &mutex_attr);
986 pthread_mutex_lock(&(result->output_lock));
988 pthread_attr_init(&attr);
989 pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_compress_loop, result);
994 void mjpeg_delete_compressor(mjpeg_compressor *engine)
997 pthread_mutex_unlock(&(engine->input_lock));
998 pthread_join(engine->tid, 0);
999 pthread_mutex_destroy(&(engine->input_lock));
1000 pthread_mutex_destroy(&(engine->output_lock));
1001 jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
1002 if(engine->output_buffer) delete [] engine->output_buffer;
1003 delete_rows(engine);
1004 delete [] engine->mcu_rows[0];
1005 delete [] engine->mcu_rows[1];
1006 delete [] engine->mcu_rows[2];
1010 unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
1012 return mjpeg->output_data;
1015 long mjpeg_output_field2(mjpeg_t *mjpeg)
1017 return mjpeg->output_field2;
1020 long mjpeg_output_size(mjpeg_t *mjpeg)
1022 return mjpeg->output_size;
1025 long mjpeg_output_allocated(mjpeg_t *mjpeg)
1027 return mjpeg->output_allocated;
1030 void mjpeg_set_output_size(mjpeg_t *mjpeg, long output_size)
1032 mjpeg->output_size = output_size;
1036 int mjpeg_compress(mjpeg_t *mjpeg,
1037 unsigned char **row_pointers,
1038 unsigned char *y_plane,
1039 unsigned char *u_plane,
1040 unsigned char *v_plane,
1045 int corrected_fields = mjpeg->fields;
1046 mjpeg->color_model = color_model;
1049 //printf("mjpeg_compress 1 %d\n", color_model);
1050 /* Reset output buffer */
1051 reset_buffer(&mjpeg->output_data,
1052 &mjpeg->output_size,
1053 &mjpeg->output_allocated);
1055 /* Create compression engines as needed */
1056 for(i = 0; i < mjpeg->fields; i++)
1058 if(!mjpeg->compressors[i])
1060 mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
1064 /* Arm YUV buffers */
1065 mjpeg->row_argument = row_pointers;
1066 mjpeg->y_argument = y_plane;
1067 mjpeg->u_argument = u_plane;
1068 mjpeg->v_argument = v_plane;
1069 // User colormodel doesn't match encoder colormodel
1070 // Copy to interlacing buffer first
1071 if(mjpeg->color_model != mjpeg->jpeg_color_model ||
1072 mjpeg->output_w != mjpeg->coded_w ||
1073 mjpeg->output_h != mjpeg->coded_h)
1076 * printf("mjpeg_compress %d %d %d %d\n",
1077 * mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_h);
1079 BC_CModels::transfer(0,
1081 mjpeg->temp_rows[0][0],
1082 mjpeg->temp_rows[1][0],
1083 mjpeg->temp_rows[2][0],
1096 mjpeg->jpeg_color_model,
1102 /* Start the compressors on the image fields */
1103 if(mjpeg->deinterlace) corrected_fields = 1;
1104 for(i = 0; i < corrected_fields && !result; i++)
1106 unlock_compress_loop(mjpeg->compressors[i]);
1108 if(mjpeg->cpus < 2 && i < corrected_fields - 1)
1110 lock_compress_loop(mjpeg->compressors[i]);
1114 /* Wait for the compressors and store in master output */
1115 for(i = 0; i < corrected_fields && !result; i++)
1117 if(mjpeg->cpus > 1 || i == corrected_fields - 1)
1119 lock_compress_loop(mjpeg->compressors[i]);
1122 append_buffer(&mjpeg->output_data,
1123 &mjpeg->output_size,
1124 &mjpeg->output_allocated,
1125 mjpeg->compressors[i]->output_buffer,
1126 mjpeg->compressors[i]->output_size);
1127 if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
1130 if(corrected_fields < mjpeg->fields)
1132 append_buffer(&mjpeg->output_data,
1133 &mjpeg->output_size,
1134 &mjpeg->output_allocated,
1135 mjpeg->compressors[0]->output_buffer,
1136 mjpeg->compressors[0]->output_size);
1138 //printf("mjpeg_compress 2\n");
1144 int mjpeg_decompress(mjpeg_t *mjpeg,
1145 unsigned char *buffer,
1148 unsigned char **row_pointers,
1149 unsigned char *y_plane,
1150 unsigned char *u_plane,
1151 unsigned char *v_plane,
1156 int got_first_thread = 0;
1158 //printf("mjpeg_decompress 1 %d\n", color_model);
1159 if(buffer_len == 0) return 1;
1160 if(input_field2 == 0 && mjpeg->fields > 1) return 1;
1162 //printf("mjpeg_decompress 2\n");
1163 /* Create decompression engines as needed */
1164 for(i = 0; i < mjpeg->fields; i++)
1166 if(!mjpeg->decompressors[i])
1168 mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
1172 //printf("mjpeg_decompress 3\n");
1173 /* Arm YUV buffers */
1174 mjpeg->row_argument = row_pointers;
1175 mjpeg->y_argument = y_plane;
1176 mjpeg->u_argument = u_plane;
1177 mjpeg->v_argument = v_plane;
1178 mjpeg->input_data = buffer;
1179 mjpeg->input_size = buffer_len;
1180 mjpeg->input_field2 = input_field2;
1181 mjpeg->color_model = color_model;
1184 //printf("mjpeg_decompress 4 %02x %02x %d %02x %02x\n", buffer[0], buffer[1], input_field2, buffer[input_field2], buffer[input_field2 + 1]);
1185 /* Start decompressors */
1186 for(i = 0; i < mjpeg->fields && !result; i++)
1188 //printf("mjpeg_decompress 5\n");
1189 unlock_compress_loop(mjpeg->decompressors[i]);
1190 //printf("mjpeg_decompress 6\n");
1192 // For dual CPUs, don't want second thread to start until temp data is allocated by the first.
1193 // For single CPUs, don't want two threads running simultaneously
1194 if(mjpeg->cpus < 2 || !mjpeg->temp_data)
1196 //printf("mjpeg_decompress 7\n");
1197 lock_compress_loop(mjpeg->decompressors[i]);
1198 //printf("mjpeg_decompress 8\n");
1199 if(i == 0) got_first_thread = 1;
1203 //printf("mjpeg_decompress 10\n");
1204 /* Wait for decompressors */
1205 for(i = 0; i < mjpeg->fields && !result; i++)
1209 if(i > 0 || !got_first_thread)
1210 lock_compress_loop(mjpeg->decompressors[i]);
1214 /* Convert colormodel */
1215 // User colormodel didn't match decompressor
1217 * if(!mjpeg->error &&
1218 * (mjpeg->jpeg_color_model != mjpeg->color_model ||
1219 * mjpeg->coded_w != mjpeg->output_w ||
1220 * mjpeg->coded_h != mjpeg->output_h))
1223 //printf("mjpeg_decompress 6 %d %d %d %d\n", mjpeg->coded_w, mjpeg->coded_h, mjpeg->output_w, mjpeg->output_h);
1224 if((mjpeg->jpeg_color_model != mjpeg->color_model ||
1225 mjpeg->coded_w != mjpeg->output_w ||
1226 mjpeg->coded_h != mjpeg->output_h)
1228 (mjpeg->temp_data ||
1231 unsigned char *y_in = mjpeg->temp_rows[0][0];
1232 unsigned char *u_in = mjpeg->temp_rows[1][0];
1233 unsigned char *v_in = mjpeg->temp_rows[2][0];
1237 * 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",
1242 * mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w,
1243 * mjpeg->jpeg_color_model,
1244 * mjpeg->color_model);
1247 BC_CModels::transfer(row_pointers,
1263 mjpeg->jpeg_color_model,
1267 mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
1268 //printf("mjpeg_decompress 8\n");
1274 void mjpeg_set_deinterlace(mjpeg_t *mjpeg, int value)
1276 mjpeg->deinterlace = value;
1279 void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
1281 mjpeg->quality = quality;
1284 void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
1286 mjpeg->use_float = use_float;
1289 void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
1294 void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan)
1296 mjpeg->rowspan = rowspan;
1299 int mjpeg_get_fields(mjpeg_t *mjpeg)
1301 return mjpeg->fields;
1305 mjpeg_t* mjpeg_new(int w,
1309 mjpeg_t *result = new mjpeg_t();
1310 memset(result, 0, sizeof(*result));
1311 pthread_mutexattr_t mutex_attr;
1313 result->output_w = w;
1314 result->output_h = h;
1315 result->fields = fields;
1316 result->color_model = BC_RGB888;
1318 result->quality = 80;
1319 result->use_float = 0;
1321 pthread_mutexattr_init(&mutex_attr);
1322 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1323 pthread_mutex_init(&(result->decompress_init), &mutex_attr);
1326 // Calculate coded dimensions
1327 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1329 result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
1332 result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
1334 result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
1338 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1345 void mjpeg_delete(mjpeg_t *mjpeg)
1348 //printf("mjpeg_delete 1\n");
1349 for(i = 0; i < mjpeg->fields; i++)
1351 //printf("mjpeg_delete 2\n");
1352 if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
1353 //printf("mjpeg_delete 3\n");
1354 if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
1355 //printf("mjpeg_delete 4\n");
1357 //printf("mjpeg_delete 5\n");
1358 delete_temps(mjpeg);
1359 //printf("mjpeg_delete 6\n");
1360 delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
1361 //printf("mjpeg_delete 7\n");
1363 //printf("mjpeg_delete 2\n");
1367 /* Open up a space to insert a marker */
1368 static void insert_space(unsigned char **buffer,
1370 long *buffer_allocated,
1375 // Make sure enough space is available
1376 if(*buffer_allocated - *buffer_size < space_len)
1378 *buffer_allocated += space_len;
1379 unsigned char *new_buffer = new unsigned char[*buffer_allocated];
1380 memcpy(new_buffer, *buffer, *buffer_size);
1382 *buffer = new_buffer;
1386 for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
1390 (*buffer)[out] = (*buffer)[in];
1392 *buffer_size += space_len;
1396 static inline int nextbyte(unsigned char *data, long *offset, long length)
1398 if(length - *offset < 1) return 0;
1400 return (unsigned char)data[*offset - 1];
1403 static inline int read_int32(unsigned char *data, long *offset, long length)
1405 if(length - *offset < 4)
1411 return ((((unsigned int)data[*offset - 4]) << 24) |
1412 (((unsigned int)data[*offset - 3]) << 16) |
1413 (((unsigned int)data[*offset - 2]) << 8) |
1414 (((unsigned int)data[*offset - 1])));
1417 static inline int read_int16(unsigned char *data, long *offset, long length)
1419 if(length - *offset < 2)
1426 return ((((unsigned int)data[*offset - 2]) << 8) |
1427 (((unsigned int)data[*offset - 1])));
1430 static inline unsigned char read_char(unsigned char *data, long *offset, long length)
1432 if(length - *offset < 1)
1439 return (unsigned char)data[*offset - 1];
1442 static inline int next_int16(unsigned char *data, long *offset, long length)
1444 if(length - *offset < 2)
1449 return ((((unsigned int)data[*offset]) << 8) |
1450 (((unsigned int)data[*offset + 1])));
1453 static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
1455 if(length - *offset < 4)
1462 data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
1463 data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
1464 data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
1465 data[(*offset)++] = (unsigned char)(value & 0xff);
1469 static inline void write_char(unsigned char *data, long *offset, long length, unsigned char value)
1471 if(length - *offset < 1)
1477 data[(*offset)++] = value;
1481 static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
1483 while(*offset < buffer_size - 1) {
1484 if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff) {
1486 return buffer[*offset - 1];
1493 /* Find the next marker after offset and return 0 on success */
1494 static int find_marker(unsigned char *buffer,
1497 unsigned long marker_type)
1501 while(!result && *offset < buffer_size - 1)
1503 unsigned int marker = next_marker(buffer, offset, buffer_size);
1504 if(marker == (marker_type & 0xff)) result = 1;
1514 int padded_field_size;
1527 int unpadded_field_size;
1530 #define LML_MARKER_SIZE 0x2c
1531 #define LML_MARKER_TAG 0xffe3
1532 void insert_lml33_markers(unsigned char **buffer,
1533 long *field2_offset,
1535 long *buffer_allocated)
1537 long marker_offset = -1;
1539 /* Search for existing marker to replace */
1540 // marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);
1542 /* Insert new marker */
1543 if(marker_offset < 0)
1546 insert_space(buffer,
1554 static int qt_table_offsets(unsigned char *buffer,
1565 bzero(header, sizeof(qt_hdr_t) * 2);
1567 // Read every marker to get the offsets for the headers
1568 for(field = 0; field < 2; field++)
1574 marker = next_marker(buffer,
1583 // The first field may be padded
1586 header[0].next_offset =
1587 header[0].padded_field_size =
1594 // Quicktime marker already exists. Abort.
1595 if(buffer[offset + 6] == 'm' &&
1596 buffer[offset + 7] == 'j' &&
1597 buffer[offset + 8] == 'p' &&
1598 buffer[offset + 9] == 'a')
1606 if(!header[field].quant_offset)
1608 header[field].quant_offset = offset - 2;
1610 header[field].quant_offset -= header[0].next_offset;
1612 len = read_int16(buffer, &offset, buffer_size);
1617 if(!header[field].huffman_offset)
1619 header[field].huffman_offset = offset - 2;
1621 header[field].huffman_offset -= header[0].next_offset;
1623 len = read_int16(buffer, &offset, buffer_size);
1628 if(!header[field].image_offset)
1630 header[field].image_offset = offset - 2;
1632 header[field].image_offset -= header[0].next_offset;
1634 len = read_int16(buffer, &offset, buffer_size);
1639 header[field].scan_offset = offset - 2;
1641 header[field].scan_offset -= header[0].next_offset;
1642 len = read_int16(buffer, &offset, buffer_size);
1644 header[field].data_offset = offset + len;
1646 header[field].data_offset -= header[0].next_offset;
1653 header[field].field_size =
1654 header[field].padded_field_size =
1655 offset - header[0].next_offset;
1656 header[field].next_offset = 0;
1660 // Often misses second SOI but gets first EOI
1661 // header[0].next_offset =
1662 // header[0].padded_field_size =
1665 //printf("table_offsets M_EOI %d %x\n", field, offset);
1671 // Junk appears between fields
1673 // len = read_int16(buffer, &offset, buffer_size);
1678 if(!done) offset += len;
1679 if(offset >= buffer_size) done = 1;
1681 //printf("qt_table_offsets 10 %d\n", field);
1687 static void insert_quicktime_marker(unsigned char *buffer,
1692 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1693 ((unsigned long)M_APP1 << 16) |
1694 (QUICKTIME_MARKER_SIZE - 2));
1695 write_int32(buffer, &offset, buffer_size, 0);
1696 write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1697 write_int32(buffer, &offset, buffer_size, header->field_size);
1698 write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1699 write_int32(buffer, &offset, buffer_size, header->next_offset);
1700 write_int32(buffer, &offset, buffer_size, header->quant_offset);
1701 write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1702 write_int32(buffer, &offset, buffer_size, header->image_offset);
1703 write_int32(buffer, &offset, buffer_size, header->scan_offset);
1704 write_int32(buffer, &offset, buffer_size, header->data_offset);
1708 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1710 long *buffer_allocated,
1712 long *field2_offset)
1716 *field2_offset = -1;
1718 if(fields < 2) return;
1721 // Get offsets for tables in both fields
1722 exists = qt_table_offsets(*buffer, *buffer_size, header);
1724 // APP1 for quicktime already exists
1727 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1728 // header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1729 //if(*field2_offset == 0)
1730 // fwrite(*buffer, *buffer_size, 1, stdout);
1734 header[0].field_size += QUICKTIME_MARKER_SIZE;
1735 header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1736 header[0].next_offset += QUICKTIME_MARKER_SIZE;
1737 header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1738 header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1739 header[0].image_offset += QUICKTIME_MARKER_SIZE;
1740 header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1741 header[0].data_offset += QUICKTIME_MARKER_SIZE;
1742 header[1].field_size += QUICKTIME_MARKER_SIZE;
1743 header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1744 header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1745 header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1746 header[1].image_offset += QUICKTIME_MARKER_SIZE;
1747 header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1748 header[1].data_offset += QUICKTIME_MARKER_SIZE;
1749 *field2_offset = header[0].next_offset;
1753 // Insert APP1 marker
1754 insert_space(buffer,
1758 QUICKTIME_MARKER_SIZE);
1760 insert_quicktime_marker(*buffer,
1765 insert_space(buffer,
1768 header[0].next_offset + 2,
1769 QUICKTIME_MARKER_SIZE);
1771 header[1].next_offset = 0;
1772 insert_quicktime_marker(*buffer,
1774 header[0].next_offset + 2,
1779 static int avi_table_offsets(unsigned char *buffer,
1783 int field2 = mjpeg_get_field2(buffer, buffer_size);
1785 header[0].field_number = 1;
1786 header[0].field_size = field2;
1787 header[0].unpadded_field_size = field2;
1789 header[1].field_number = 2;
1790 header[1].field_size = buffer_size - field2;
1791 header[1].unpadded_field_size = buffer_size - field2;
1795 static void insert_avi_marker(unsigned char *buffer,
1800 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1801 ((unsigned long)M_APP0 << 16) |
1802 (AVI_MARKER_SIZE - 2));
1803 write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1805 // One version of McRoweSoft only allows field polarity while
1806 // another version allows field size.
1807 write_char(buffer, &offset, buffer_size, header->field_number);
1808 write_char(buffer, &offset, buffer_size, 0);
1809 write_int32(buffer, &offset, buffer_size, header->field_size);
1810 write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1813 void mjpeg_insert_avi_markers(unsigned char **buffer,
1815 long *buffer_allocated,
1817 long *field2_offset)
1819 avi_hdr_t header[2];
1821 *field2_offset = -1;
1824 // Test for existing marker
1825 if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1827 if((*buffer)[offset + 2] == 'A' &&
1828 (*buffer)[offset + 3] == 'V' &&
1829 (*buffer)[offset + 4] == 'I' &&
1830 (*buffer)[offset + 5] == '1')
1835 avi_table_offsets(*buffer, *buffer_size, header);
1837 header[0].field_size += AVI_MARKER_SIZE;
1838 header[0].unpadded_field_size += AVI_MARKER_SIZE;
1839 header[1].field_size += AVI_MARKER_SIZE;
1840 header[1].unpadded_field_size += AVI_MARKER_SIZE;
1841 *field2_offset = header[0].field_size;
1843 // Insert APP0 marker into field 1
1844 insert_space(buffer,
1849 insert_avi_marker(*buffer,
1854 insert_space(buffer,
1859 insert_avi_marker(*buffer,
1869 static void read_avi_markers(unsigned char *buffer,
1874 int marker_count = 0;
1876 int marker_size = 0;
1877 while(marker_count < 2 && offset < buffer_size && !result)
1879 result = find_marker(buffer,
1883 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1886 if(!result && marker_size >= 16)
1888 // Marker size, AVI1
1891 header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1892 read_char(buffer, &offset, buffer_size);
1893 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1894 header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1901 static void read_quicktime_markers(unsigned char *buffer,
1906 int marker_count = 0;
1909 while(marker_count < 2 && offset < buffer_size && !result)
1911 result = find_marker(buffer,
1919 read_int16(buffer, &offset, buffer_size);
1921 read_int32(buffer, &offset, buffer_size);
1923 read_int32(buffer, &offset, buffer_size);
1925 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1926 header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1927 header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1928 header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1929 header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1930 header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1931 header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1932 header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1936 //printf("read_quicktime_markers 1 %d\n", marker_count);
1939 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1942 bzero(&header, sizeof(qt_hdr_t) * 2);
1944 read_quicktime_markers(buffer, buffer_size, header);
1945 return header[0].next_offset;
1948 long mjpeg_get_avi_field2(unsigned char *buffer,
1950 int *field_dominance)
1952 avi_hdr_t header[2];
1953 bzero(&header, sizeof(avi_hdr_t) * 2);
1954 read_avi_markers(buffer, buffer_size, header);
1956 *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1958 // One version of McRoweSoft only allows field polarity while
1959 // another version allows field size.
1960 if(header[0].field_size)
1962 return header[0].field_size;
1966 return mjpeg_get_field2(buffer, buffer_size);
1971 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1973 int total_fields = 0;
1974 long field2_offset = 0;
1977 for(i = 0; i < buffer_size; i++)
1979 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1983 if(total_fields == 2) break;
1986 return field2_offset;
1989 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1996 *h = (data[offset + 3] << 8) | (data[offset + 4]);
1997 *w = (data[offset + 5] << 8) | (data[offset + 6]);