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
20 #include "colormodels.h"
78 #define QUICKTIME_MARKER_SIZE 0x2c
79 #define AVI_MARKER_SIZE 0x12
80 #define QUICKTIME_JPEG_TAG 0x6d6a7067
81 #define QUICKTIME_AVI_TAG 0x41564931
84 METHODDEF(void) mjpeg_error_exit (j_common_ptr cinfo
)
86 /* cinfo->err really points to a mjpeg_error_mgr struct, so coerce pointer */
87 mjpeg_error_ptr mjpegerr
= (mjpeg_error_ptr
) cinfo
->err
;
89 /* Always display the message. */
90 /* We could postpone this until after returning, if we chose. */
91 (*cinfo
->err
->output_message
) (cinfo
);
93 /* Return control to the setjmp point */
94 longjmp(mjpegerr
->setjmp_buffer
, 1);
99 struct jpeg_destination_mgr pub
; /* public fields */
101 JOCTET
*buffer
; /* Pointer to buffer */
102 mjpeg_compressor
*engine
;
103 } mjpeg_destination_mgr
;
105 typedef mjpeg_destination_mgr
*mjpeg_dest_ptr
;
109 * Initialize destination --- called by jpeg_start_compress
110 * before any data is actually written.
113 METHODDEF(void) init_destination(j_compress_ptr cinfo
)
115 mjpeg_dest_ptr dest
= (mjpeg_dest_ptr
)cinfo
->dest
;
117 /* Set the pointer to the preallocated buffer */
118 if(!dest
->engine
->output_buffer
)
120 dest
->engine
->output_buffer
= calloc(1, 65536);
121 dest
->engine
->output_allocated
= 65536;
123 dest
->buffer
= dest
->engine
->output_buffer
;
124 dest
->pub
.next_output_byte
= dest
->engine
->output_buffer
;
125 dest
->pub
.free_in_buffer
= dest
->engine
->output_allocated
;
129 * Empty the output buffer --- called whenever buffer fills up.
131 * In typical applications, this should write the entire output buffer
132 * (ignoring the current state of next_output_byte & free_in_buffer),
133 * reset the pointer & count to the start of the buffer, and return TRUE
134 * indicating that the buffer has been dumped.
136 * In applications that need to be able to suspend compression due to output
137 * overrun, a FALSE return indicates that the buffer cannot be emptied now.
138 * In this situation, the compressor will return to its caller (possibly with
139 * an indication that it has not accepted all the supplied scanlines). The
140 * application should resume compression after it has made more room in the
141 * output buffer. Note that there are substantial restrictions on the use of
142 * suspension --- see the documentation.
144 * When suspending, the compressor will back up to a convenient restart point
145 * (typically the start of the current MCU). next_output_byte & free_in_buffer
146 * indicate where the restart point will be if the current call returns FALSE.
147 * Data beyond this point will be regenerated after resumption, so do not
148 * write it out when emptying the buffer externally.
151 METHODDEF(boolean
) empty_output_buffer(j_compress_ptr cinfo
)
153 /* Allocate a bigger buffer. */
154 mjpeg_dest_ptr dest
= (mjpeg_dest_ptr
)cinfo
->dest
;
156 dest
->engine
->output_size
= dest
->engine
->output_allocated
;
157 dest
->engine
->output_allocated
*= 2;
158 dest
->engine
->output_buffer
= realloc(dest
->engine
->output_buffer
,
159 dest
->engine
->output_allocated
);
160 dest
->buffer
= dest
->engine
->output_buffer
;
161 dest
->pub
.next_output_byte
= dest
->buffer
+ dest
->engine
->output_size
;
162 dest
->pub
.free_in_buffer
= dest
->engine
->output_allocated
- dest
->engine
->output_size
;
168 * Terminate destination --- called by jpeg_finish_compress
169 * after all data has been written. Usually needs to flush buffer.
171 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
172 * application must deal with any cleanup that should happen even
175 METHODDEF(void) term_destination(j_compress_ptr cinfo
)
177 /* Just get the length */
178 mjpeg_dest_ptr dest
= (mjpeg_dest_ptr
)cinfo
->dest
;
179 dest
->engine
->output_size
= dest
->engine
->output_allocated
- dest
->pub
.free_in_buffer
;
182 GLOBAL(void) jpeg_buffer_dest(j_compress_ptr cinfo
, mjpeg_compressor
*engine
)
186 /* The destination object is made permanent so that multiple JPEG images
187 * can be written to the same file without re-executing jpeg_stdio_dest.
188 * This makes it dangerous to use this manager and a different destination
189 * manager serially with the same JPEG object, because their private object
190 * sizes may be different. Caveat programmer.
192 if(cinfo
->dest
== NULL
)
194 /* first time for this JPEG object? */
195 cinfo
->dest
= (struct jpeg_destination_mgr
*)
196 (*cinfo
->mem
->alloc_small
)((j_common_ptr
)cinfo
,
198 sizeof(mjpeg_destination_mgr
));
201 dest
= (mjpeg_dest_ptr
)cinfo
->dest
;
202 dest
->pub
.init_destination
= init_destination
;
203 dest
->pub
.empty_output_buffer
= empty_output_buffer
;
204 dest
->pub
.term_destination
= term_destination
;
205 dest
->engine
= engine
;
222 struct jpeg_source_mgr pub
; /* public fields */
224 JOCTET
* buffer
; /* start of buffer */
225 int bytes
; /* total size of buffer */
228 typedef mjpeg_source_mgr
* mjpeg_src_ptr
;
230 METHODDEF(void) init_source(j_decompress_ptr cinfo
)
232 mjpeg_src_ptr src
= (mjpeg_src_ptr
) cinfo
->src
;
235 METHODDEF(boolean
) fill_input_buffer(j_decompress_ptr cinfo
)
237 mjpeg_src_ptr src
= (mjpeg_src_ptr
) cinfo
->src
;
239 src
->buffer
[0] = (JOCTET
)0xFF;
240 src
->buffer
[1] = (JOCTET
)M_EOI
;
241 src
->pub
.next_input_byte
= src
->buffer
;
242 src
->pub
.bytes_in_buffer
= 2;
248 METHODDEF(void) skip_input_data(j_decompress_ptr cinfo
, long num_bytes
)
250 mjpeg_src_ptr src
= (mjpeg_src_ptr
)cinfo
->src
;
252 src
->pub
.next_input_byte
+= (size_t)num_bytes
;
253 src
->pub
.bytes_in_buffer
-= (size_t)num_bytes
;
257 METHODDEF(void) term_source(j_decompress_ptr cinfo
)
261 GLOBAL(void) jpeg_buffer_src(j_decompress_ptr cinfo
, unsigned char *buffer
, long bytes
)
265 /* first time for this JPEG object? */
266 if(cinfo
->src
== NULL
)
268 cinfo
->src
= (struct jpeg_source_mgr
*)
269 (*cinfo
->mem
->alloc_small
)((j_common_ptr
)cinfo
,
271 sizeof(mjpeg_source_mgr
));
272 src
= (mjpeg_src_ptr
)cinfo
->src
;
275 src
= (mjpeg_src_ptr
)cinfo
->src
;
276 src
->pub
.init_source
= init_source
;
277 src
->pub
.fill_input_buffer
= fill_input_buffer
;
278 src
->pub
.skip_input_data
= skip_input_data
;
279 src
->pub
.resync_to_restart
= jpeg_resync_to_restart
; /* use default method */
280 src
->pub
.term_source
= term_source
;
281 src
->pub
.bytes_in_buffer
= bytes
;
282 src
->pub
.next_input_byte
= buffer
;
283 src
->buffer
= buffer
;
287 /* JPEG DHT Segment for YCrCb omitted from MJPEG data */
289 unsigned char jpeg_odml_dht
[0x1a4] = {
290 0xff, 0xc4, 0x01, 0xa2,
292 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
295 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
298 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
299 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
300 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
301 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
302 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
303 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
304 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
305 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
306 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
307 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
308 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
311 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
312 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
313 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
314 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
315 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
316 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
317 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
318 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
319 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
320 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
321 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
327 * Parse the DHT table.
328 * This code comes from jpeg6b (jdmarker.c).
331 int jpeg_load_dht (struct jpeg_decompress_struct
*info
, unsigned char *dht
,
332 JHUFF_TBL
*ac_tables
[], JHUFF_TBL
*dc_tables
[])
334 unsigned int length
= (dht
[2] << 8) + dht
[3] - 2;
335 unsigned int pos
= 4;
336 unsigned int count
, i
;
340 unsigned char bits
[17];
341 unsigned char huffval
[256];
348 for (i
= 1; i
<= 16; ++i
)
350 bits
[i
] = dht
[pos
++];
355 if (count
> 256 || count
> length
)
358 for (i
= 0; i
< count
; ++i
)
359 huffval
[i
] = dht
[pos
++];
365 hufftbl
= &ac_tables
[index
];
368 hufftbl
= &dc_tables
[index
];
370 if (index
< 0 || index
>= NUM_HUFF_TBLS
)
373 if (*hufftbl
== NULL
)
374 *hufftbl
= jpeg_alloc_huff_table ((j_common_ptr
)info
);
375 if (*hufftbl
== NULL
)
378 memcpy ((*hufftbl
)->bits
, bits
, sizeof (*hufftbl
)->bits
);
379 memcpy ((*hufftbl
)->huffval
, huffval
, sizeof (*hufftbl
)->huffval
);
402 static void reset_buffer(unsigned char **buffer
, long *size
, long *allocated
)
407 static void delete_buffer(unsigned char **buffer
, long *size
, long *allocated
)
417 static void append_buffer(unsigned char **buffer
,
425 *buffer
= calloc(1, 65536);
430 if(*size
+ data_size
+ 0x100 > *allocated
)
432 *allocated
= *size
+ data_size
+ 0x100;
433 *buffer
= realloc(*buffer
, *allocated
);
436 memcpy(*buffer
+ *size
, data
, data_size
);
440 static void allocate_temps(mjpeg_t
*mjpeg
)
444 if(!mjpeg
->temp_data
)
446 switch(mjpeg
->jpeg_color_model
)
449 mjpeg
->temp_data
= calloc(1, mjpeg
->coded_w
* mjpeg
->coded_h
* 2);
450 mjpeg
->temp_rows
[0] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
);
451 mjpeg
->temp_rows
[1] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
);
452 mjpeg
->temp_rows
[2] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
);
453 for(i
= 0; i
< mjpeg
->coded_h
; i
++)
455 mjpeg
->temp_rows
[0][i
] = mjpeg
->temp_data
+ i
* mjpeg
->coded_w
;
456 mjpeg
->temp_rows
[1][i
] = mjpeg
->temp_data
+ mjpeg
->coded_w
* mjpeg
->coded_h
+ i
* mjpeg
->coded_w
/ 2;
457 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;
462 mjpeg
->temp_data
= calloc(1, mjpeg
->coded_w
* mjpeg
->coded_h
* 3);
463 mjpeg
->temp_rows
[0] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
);
464 mjpeg
->temp_rows
[1] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
);
465 mjpeg
->temp_rows
[2] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
);
468 memset(mjpeg
->temp_data
+ mjpeg
->coded_w
* mjpeg
->coded_h
,
470 mjpeg
->coded_w
* mjpeg
->coded_h
* 2);
472 for(i
= 0; i
< mjpeg
->coded_h
; i
++)
474 mjpeg
->temp_rows
[0][i
] = mjpeg
->temp_data
+ i
* mjpeg
->coded_w
;
475 mjpeg
->temp_rows
[1][i
] = mjpeg
->temp_data
+ mjpeg
->coded_w
* mjpeg
->coded_h
+ i
* mjpeg
->coded_w
;
476 mjpeg
->temp_rows
[2][i
] = mjpeg
->temp_data
+ mjpeg
->coded_w
* mjpeg
->coded_h
+ mjpeg
->coded_w
* mjpeg
->coded_h
+ i
* mjpeg
->coded_w
;
481 mjpeg
->temp_data
= calloc(1, mjpeg
->coded_w
* mjpeg
->coded_h
+ mjpeg
->coded_w
* mjpeg
->coded_h
/ 2);
482 mjpeg
->temp_rows
[0] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
);
483 mjpeg
->temp_rows
[1] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
/ 2);
484 mjpeg
->temp_rows
[2] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
/ 2);
485 for(i
= 0; i
< mjpeg
->coded_h
; i
++)
487 mjpeg
->temp_rows
[0][i
] = mjpeg
->temp_data
+ i
* mjpeg
->coded_w
;
488 if(i
< mjpeg
->coded_h
/ 2)
490 mjpeg
->temp_rows
[1][i
] = mjpeg
->temp_data
+ mjpeg
->coded_w
* mjpeg
->coded_h
+ i
* (mjpeg
->coded_w
/ 2);
491 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);
499 static int get_input_row(mjpeg_t
*mjpeg
, mjpeg_compressor
*compressor
, int i
)
502 if(mjpeg
->fields
> 1)
503 input_row
= i
* 2 + compressor
->instance
;
506 if(input_row
>= mjpeg
->coded_h
) input_row
= mjpeg
->coded_h
- 1;
510 // Get pointers to rows for the JPEG compressor
511 static void get_rows(mjpeg_t
*mjpeg
, mjpeg_compressor
*compressor
)
514 switch(mjpeg
->jpeg_color_model
)
518 if(!compressor
->rows
[0])
520 compressor
->rows
[0] = calloc(1, sizeof(unsigned char*) * compressor
->coded_field_h
);
521 compressor
->rows
[1] = calloc(1, sizeof(unsigned char*) * compressor
->coded_field_h
);
522 compressor
->rows
[2] = calloc(1, sizeof(unsigned char*) * compressor
->coded_field_h
);
525 // User colormodel matches jpeg colormodel
526 if(mjpeg
->color_model
== BC_YUV444P
&&
527 mjpeg
->output_w
== mjpeg
->coded_w
&&
528 mjpeg
->output_h
== mjpeg
->coded_h
)
530 for(i
= 0; i
< compressor
->coded_field_h
; i
++)
532 int input_row
= get_input_row(mjpeg
, compressor
, i
);
533 compressor
->rows
[0][i
] = mjpeg
->y_argument
+
534 mjpeg
->coded_w
* input_row
;
535 compressor
->rows
[1][i
] = mjpeg
->u_argument
+
536 mjpeg
->coded_w
* input_row
;
537 compressor
->rows
[2][i
] = mjpeg
->v_argument
+
538 mjpeg
->coded_w
* input_row
;
543 for(i
= 0; i
< compressor
->coded_field_h
; i
++)
545 int input_row
= get_input_row(mjpeg
, compressor
, i
);
546 compressor
->rows
[0][i
] = mjpeg
->temp_rows
[0][input_row
];
547 compressor
->rows
[1][i
] = mjpeg
->temp_rows
[1][input_row
];
548 compressor
->rows
[2][i
] = mjpeg
->temp_rows
[2][input_row
];
556 if(!compressor
->rows
[0])
558 compressor
->rows
[0] = calloc(1, sizeof(unsigned char*) * compressor
->coded_field_h
);
559 compressor
->rows
[1] = calloc(1, sizeof(unsigned char*) * compressor
->coded_field_h
);
560 compressor
->rows
[2] = calloc(1, sizeof(unsigned char*) * compressor
->coded_field_h
);
563 // User colormodel matches jpeg colormodel
564 if(mjpeg
->color_model
== BC_YUV422P
&&
565 mjpeg
->output_w
== mjpeg
->coded_w
&&
566 mjpeg
->output_h
== mjpeg
->coded_h
)
568 for(i
= 0; i
< compressor
->coded_field_h
; i
++)
570 int input_row
= get_input_row(mjpeg
, compressor
, i
);
571 compressor
->rows
[0][i
] = mjpeg
->y_argument
+
572 mjpeg
->coded_w
* input_row
;
573 compressor
->rows
[1][i
] = mjpeg
->u_argument
+
574 (mjpeg
->coded_w
/ 2) * input_row
;
575 compressor
->rows
[2][i
] = mjpeg
->v_argument
+
576 (mjpeg
->coded_w
/ 2) * input_row
;
581 for(i
= 0; i
< compressor
->coded_field_h
; i
++)
583 int input_row
= get_input_row(mjpeg
, compressor
, i
);
584 compressor
->rows
[0][i
] = mjpeg
->temp_rows
[0][input_row
];
585 compressor
->rows
[1][i
] = mjpeg
->temp_rows
[1][input_row
];
586 compressor
->rows
[2][i
] = mjpeg
->temp_rows
[2][input_row
];
594 if(!compressor
->rows
[0])
596 compressor
->rows
[0] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
);
597 compressor
->rows
[1] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
/ 2);
598 compressor
->rows
[2] = calloc(1, sizeof(unsigned char*) * mjpeg
->coded_h
/ 2);
601 // User colormodel matches jpeg colormodel
602 if(mjpeg
->color_model
== BC_YUV420P
&&
603 mjpeg
->output_w
== mjpeg
->coded_w
&&
604 mjpeg
->output_h
== mjpeg
->coded_h
)
606 for(i
= 0; i
< compressor
->coded_field_h
; i
++)
608 int input_row
= get_input_row(mjpeg
, compressor
, i
);
609 compressor
->rows
[0][i
] = mjpeg
->y_argument
+
610 mjpeg
->coded_w
* input_row
;
611 if(i
< compressor
->coded_field_h
/ 2)
613 compressor
->rows
[1][i
] = mjpeg
->u_argument
+
614 (mjpeg
->coded_w
/ 2) * input_row
;
615 compressor
->rows
[2][i
] = mjpeg
->v_argument
+
616 (mjpeg
->coded_w
/ 2) * input_row
;
622 for(i
= 0; i
< compressor
->coded_field_h
; i
++)
624 int input_row
= get_input_row(mjpeg
, compressor
, i
);
625 compressor
->rows
[0][i
] = mjpeg
->temp_rows
[0][input_row
];
626 if(i
< compressor
->coded_field_h
/ 2)
628 compressor
->rows
[1][i
] = mjpeg
->temp_rows
[1][input_row
];
629 compressor
->rows
[2][i
] = mjpeg
->temp_rows
[2][input_row
];
638 static void delete_rows(mjpeg_compressor
*compressor
)
640 if(compressor
->rows
[0])
642 free(compressor
->rows
[0]);
643 free(compressor
->rows
[1]);
644 free(compressor
->rows
[2]);
649 static void new_jpeg_objects(mjpeg_compressor
*engine
)
651 engine
->jpeg_decompress
.err
= jpeg_std_error(&(engine
->jpeg_error
.pub
));
652 engine
->jpeg_error
.pub
.error_exit
= mjpeg_error_exit
;
653 /* Ideally the error handler would be set here but it must be called in a thread */
654 jpeg_create_decompress(&(engine
->jpeg_decompress
));
655 engine
->jpeg_decompress
.raw_data_out
= TRUE
;
656 engine
->jpeg_decompress
.dct_method
= JDCT_IFAST
;
659 static void delete_jpeg_objects(mjpeg_compressor
*engine
)
661 jpeg_destroy_decompress(&(engine
->jpeg_decompress
));
666 static void unlock_compress_loop(mjpeg_compressor
*engine
)
668 pthread_mutex_unlock(&(engine
->input_lock
));
671 static void lock_compress_loop(mjpeg_compressor
*engine
)
673 pthread_mutex_lock(&(engine
->output_lock
));
676 // Make temp rows for compressor
677 static void get_mcu_rows(mjpeg_t
*mjpeg
,
678 mjpeg_compressor
*engine
,
682 for(i
= 0; i
< 3; i
++)
684 for(j
= 0; j
< 16; j
++)
686 if(i
> 0 && j
>= 8 && mjpeg
->jpeg_color_model
== BC_YUV420P
) break;
688 scanline
= start_row
;
689 if(i
> 0 && mjpeg
->jpeg_color_model
== BC_YUV420P
) scanline
/= 2;
691 if(scanline
>= engine
->coded_field_h
) scanline
= engine
->coded_field_h
- 1;
692 engine
->mcu_rows
[i
][j
] = engine
->rows
[i
][scanline
];
698 static void decompress_field(mjpeg_compressor
*engine
)
700 mjpeg_t
*mjpeg
= engine
->mjpeg
;
701 long buffer_offset
= engine
->instance
* mjpeg
->input_field2
;
702 unsigned char *buffer
= mjpeg
->input_data
+ buffer_offset
;
706 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
707 if(engine
->instance
== 0 && mjpeg
->fields
> 1)
708 buffer_size
= mjpeg
->input_field2
- buffer_offset
;
710 buffer_size
= mjpeg
->input_size
- buffer_offset
;
714 if(setjmp(engine
->jpeg_error
.setjmp_buffer
))
716 /* If we get here, the JPEG code has signaled an error. */
717 delete_jpeg_objects(engine
);
718 new_jpeg_objects(engine
);
720 //printf("decompress_field 1\n");
724 //printf("decompress_field 2\n");
725 jpeg_buffer_src(&engine
->jpeg_decompress
,
728 jpeg_read_header(&engine
->jpeg_decompress
, TRUE
);
730 if ( engine
->jpeg_decompress
.ac_huff_tbl_ptrs
[0] == NULL
&&
731 engine
->jpeg_decompress
.ac_huff_tbl_ptrs
[1] == NULL
&&
732 engine
->jpeg_decompress
.dc_huff_tbl_ptrs
[0] == NULL
&&
733 engine
->jpeg_decompress
.dc_huff_tbl_ptrs
[1] == NULL
)
734 jpeg_load_dht( &engine
->jpeg_decompress
,
736 engine
->jpeg_decompress
.ac_huff_tbl_ptrs
,
737 engine
->jpeg_decompress
.dc_huff_tbl_ptrs
);
738 // Reset by jpeg_read_header
739 engine
->jpeg_decompress
.raw_data_out
= TRUE
;
740 jpeg_start_decompress(&engine
->jpeg_decompress
);
742 // Generate colormodel from jpeg sampling
743 if(engine
->jpeg_decompress
.comp_info
[0].v_samp_factor
== 2 &&
744 engine
->jpeg_decompress
.comp_info
[0].h_samp_factor
== 2)
745 mjpeg
->jpeg_color_model
= BC_YUV420P
;
747 if(engine
->jpeg_decompress
.comp_info
[0].v_samp_factor
== 1 &&
748 engine
->jpeg_decompress
.comp_info
[0].h_samp_factor
== 2)
749 mjpeg
->jpeg_color_model
= BC_YUV422P
;
751 mjpeg
->jpeg_color_model
= BC_YUV444P
;
753 if(engine
->jpeg_decompress
.jpeg_color_space
== JCS_GRAYSCALE
)
754 mjpeg
->greyscale
= 1;
756 //printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor);
757 // Must be here because the color model isn't known until now
758 pthread_mutex_lock(&(mjpeg
->decompress_init
));
759 allocate_temps(mjpeg
);
760 pthread_mutex_unlock(&(mjpeg
->decompress_init
));
761 get_rows(mjpeg
, engine
);
764 while(engine
->jpeg_decompress
.output_scanline
< engine
->jpeg_decompress
.output_height
)
766 get_mcu_rows(mjpeg
, engine
, engine
->jpeg_decompress
.output_scanline
);
767 jpeg_read_raw_data(&engine
->jpeg_decompress
,
769 engine
->coded_field_h
);
771 jpeg_finish_decompress(&engine
->jpeg_decompress
);
778 void mjpeg_decompress_loop(mjpeg_compressor
*engine
)
782 pthread_mutex_lock(&engine
->input_lock
);
785 decompress_field(engine
);
787 pthread_mutex_unlock(&(engine
->output_lock
));
792 static void compress_field(mjpeg_compressor
*engine
)
795 mjpeg_t
*mjpeg
= engine
->mjpeg
;
797 //printf("compress_field 1\n");
798 get_rows(engine
->mjpeg
, engine
);
799 reset_buffer(&engine
->output_buffer
, &engine
->output_size
, &engine
->output_allocated
);
800 jpeg_buffer_dest(&engine
->jpeg_compress
, engine
);
803 engine
->jpeg_compress
.raw_data_in
= TRUE
;
804 jpeg_start_compress(&engine
->jpeg_compress
, TRUE
);
806 while(engine
->jpeg_compress
.next_scanline
< engine
->jpeg_compress
.image_height
)
808 get_mcu_rows(mjpeg
, engine
, engine
->jpeg_compress
.next_scanline
);
810 jpeg_write_raw_data(&engine
->jpeg_compress
,
812 engine
->coded_field_h
);
814 jpeg_finish_compress(&engine
->jpeg_compress
);
815 //printf("compress_field 2\n");
819 void mjpeg_compress_loop(mjpeg_compressor
*engine
)
823 pthread_mutex_lock(&engine
->input_lock
);
826 compress_field(engine
);
828 pthread_mutex_unlock(&engine
->output_lock
);
832 static void delete_temps(mjpeg_t
*mjpeg
)
836 free(mjpeg
->temp_data
);
837 free(mjpeg
->temp_rows
[0]);
838 free(mjpeg
->temp_rows
[1]);
839 free(mjpeg
->temp_rows
[2]);
843 mjpeg_compressor
* mjpeg_new_decompressor(mjpeg_t
*mjpeg
, int instance
)
845 mjpeg_compressor
*result
= calloc(1, sizeof(mjpeg_compressor
));
847 struct sched_param param
;
848 pthread_mutexattr_t mutex_attr
;
851 result
->mjpeg
= mjpeg
;
852 result
->instance
= instance
;
853 new_jpeg_objects(result
);
854 result
->field_h
= mjpeg
->output_h
/ mjpeg
->fields
;
855 result
->coded_field_h
= (result
->field_h
% 16) ?
856 result
->field_h
+ (16 - (result
->field_h
% 16)) : result
->field_h
;
858 result
->mcu_rows
[0] = malloc(16 * sizeof(unsigned char*));
859 result
->mcu_rows
[1] = malloc(16 * sizeof(unsigned char*));
860 result
->mcu_rows
[2] = malloc(16 * sizeof(unsigned char*));
862 pthread_mutexattr_init(&mutex_attr
);
863 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
864 pthread_mutex_init(&(result
->input_lock
), &mutex_attr
);
865 pthread_mutex_lock(&(result
->input_lock
));
866 pthread_mutex_init(&(result
->output_lock
), &mutex_attr
);
867 pthread_mutex_lock(&(result
->output_lock
));
869 pthread_attr_init(&attr
);
870 pthread_create(&(result
->tid
), &attr
, (void*)mjpeg_decompress_loop
, result
);
875 void mjpeg_delete_decompressor(mjpeg_compressor
*engine
)
878 pthread_mutex_unlock(&(engine
->input_lock
));
879 pthread_join(engine
->tid
, 0);
880 pthread_mutex_destroy(&(engine
->input_lock
));
881 pthread_mutex_destroy(&(engine
->output_lock
));
882 jpeg_destroy_decompress(&(engine
->jpeg_decompress
));
884 free(engine
->mcu_rows
[0]);
885 free(engine
->mcu_rows
[1]);
886 free(engine
->mcu_rows
[2]);
890 mjpeg_compressor
* mjpeg_new_compressor(mjpeg_t
*mjpeg
, int instance
)
893 struct sched_param param
;
894 pthread_mutexattr_t mutex_attr
;
895 mjpeg_compressor
*result
= calloc(1, sizeof(mjpeg_compressor
));
897 result
->field_h
= mjpeg
->output_h
/ mjpeg
->fields
;
898 result
->coded_field_h
= (result
->field_h
% 16) ?
899 result
->field_h
+ (16 - (result
->field_h
% 16)) : result
->field_h
;
900 result
->mjpeg
= mjpeg
;
901 result
->instance
= instance
;
902 result
->jpeg_compress
.err
= jpeg_std_error(&(result
->jpeg_error
.pub
));
903 jpeg_create_compress(&(result
->jpeg_compress
));
904 result
->jpeg_compress
.image_width
= mjpeg
->output_w
;
905 result
->jpeg_compress
.image_height
= result
->field_h
;
906 result
->jpeg_compress
.input_components
= 3;
907 result
->jpeg_compress
.in_color_space
= JCS_RGB
;
908 jpeg_set_defaults(&(result
->jpeg_compress
));
909 result
->jpeg_compress
.input_components
= 3;
910 result
->jpeg_compress
.in_color_space
= JCS_RGB
;
911 jpeg_set_quality(&(result
->jpeg_compress
), mjpeg
->quality
, 0);
914 result
->jpeg_compress
.dct_method
= JDCT_FLOAT
;
916 result
->jpeg_compress
.dct_method
= JDCT_IFAST
;
917 // result->jpeg_compress.dct_method = JDCT_ISLOW;
920 switch(mjpeg
->fields
)
923 mjpeg
->jpeg_color_model
= BC_YUV420P
;
924 result
->jpeg_compress
.comp_info
[0].h_samp_factor
= 2;
925 result
->jpeg_compress
.comp_info
[0].v_samp_factor
= 2;
926 result
->jpeg_compress
.comp_info
[1].h_samp_factor
= 1;
927 result
->jpeg_compress
.comp_info
[1].v_samp_factor
= 1;
928 result
->jpeg_compress
.comp_info
[2].h_samp_factor
= 1;
929 result
->jpeg_compress
.comp_info
[2].v_samp_factor
= 1;
932 mjpeg
->jpeg_color_model
= BC_YUV422P
;
933 result
->jpeg_compress
.comp_info
[0].h_samp_factor
= 2;
934 result
->jpeg_compress
.comp_info
[0].v_samp_factor
= 1;
935 result
->jpeg_compress
.comp_info
[1].h_samp_factor
= 1;
936 result
->jpeg_compress
.comp_info
[1].v_samp_factor
= 1;
937 result
->jpeg_compress
.comp_info
[2].h_samp_factor
= 1;
938 result
->jpeg_compress
.comp_info
[2].v_samp_factor
= 1;
941 allocate_temps(mjpeg
);
943 result
->mcu_rows
[0] = malloc(16 * sizeof(unsigned char*));
944 result
->mcu_rows
[1] = malloc(16 * sizeof(unsigned char*));
945 result
->mcu_rows
[2] = malloc(16 * sizeof(unsigned char*));
947 pthread_mutexattr_init(&mutex_attr
);
948 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
949 pthread_mutex_init(&(result
->input_lock
), &mutex_attr
);
950 pthread_mutex_lock(&(result
->input_lock
));
951 pthread_mutex_init(&(result
->output_lock
), &mutex_attr
);
952 pthread_mutex_lock(&(result
->output_lock
));
954 pthread_attr_init(&attr
);
955 pthread_create(&(result
->tid
), &attr
, (void*)mjpeg_compress_loop
, result
);
960 void mjpeg_delete_compressor(mjpeg_compressor
*engine
)
963 pthread_mutex_unlock(&(engine
->input_lock
));
964 pthread_join(engine
->tid
, 0);
965 pthread_mutex_destroy(&(engine
->input_lock
));
966 pthread_mutex_destroy(&(engine
->output_lock
));
967 jpeg_destroy((j_common_ptr
)&(engine
->jpeg_compress
));
968 if(engine
->output_buffer
) free(engine
->output_buffer
);
970 free(engine
->mcu_rows
[0]);
971 free(engine
->mcu_rows
[1]);
972 free(engine
->mcu_rows
[2]);
976 unsigned char* mjpeg_output_buffer(mjpeg_t
*mjpeg
)
978 return mjpeg
->output_data
;
981 long mjpeg_output_field2(mjpeg_t
*mjpeg
)
983 return mjpeg
->output_field2
;
986 long mjpeg_output_size(mjpeg_t
*mjpeg
)
988 return mjpeg
->output_size
;
991 long mjpeg_output_allocated(mjpeg_t
*mjpeg
)
993 return mjpeg
->output_allocated
;
996 void mjpeg_set_output_size(mjpeg_t
*mjpeg
, long output_size
)
998 mjpeg
->output_size
= output_size
;
1002 int mjpeg_compress(mjpeg_t
*mjpeg
,
1003 unsigned char **row_pointers
,
1004 unsigned char *y_plane
,
1005 unsigned char *u_plane
,
1006 unsigned char *v_plane
,
1011 int corrected_fields
= mjpeg
->fields
;
1012 mjpeg
->color_model
= color_model
;
1015 //printf("mjpeg_compress 1 %d\n", color_model);
1016 /* Reset output buffer */
1017 reset_buffer(&mjpeg
->output_data
,
1018 &mjpeg
->output_size
,
1019 &mjpeg
->output_allocated
);
1021 /* Create compression engines as needed */
1022 for(i
= 0; i
< mjpeg
->fields
; i
++)
1024 if(!mjpeg
->compressors
[i
])
1026 mjpeg
->compressors
[i
] = mjpeg_new_compressor(mjpeg
, i
);
1030 /* Arm YUV buffers */
1031 mjpeg
->row_argument
= row_pointers
;
1032 mjpeg
->y_argument
= y_plane
;
1033 mjpeg
->u_argument
= u_plane
;
1034 mjpeg
->v_argument
= v_plane
;
1035 // User colormodel doesn't match encoder colormodel
1036 // Copy to interlacing buffer first
1037 if(mjpeg
->color_model
!= mjpeg
->jpeg_color_model
||
1038 mjpeg
->output_w
!= mjpeg
->coded_w
||
1039 mjpeg
->output_h
!= mjpeg
->coded_h
)
1042 * printf("mjpeg_compress %d %d %d %d\n",
1043 * mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_h);
1047 mjpeg
->temp_rows
[0][0],
1048 mjpeg
->temp_rows
[1][0],
1049 mjpeg
->temp_rows
[2][0],
1062 mjpeg
->jpeg_color_model
,
1068 /* Start the compressors on the image fields */
1069 if(mjpeg
->deinterlace
) corrected_fields
= 1;
1070 for(i
= 0; i
< corrected_fields
&& !result
; i
++)
1072 unlock_compress_loop(mjpeg
->compressors
[i
]);
1074 if(mjpeg
->cpus
< 2 && i
< corrected_fields
- 1)
1076 lock_compress_loop(mjpeg
->compressors
[i
]);
1080 /* Wait for the compressors and store in master output */
1081 for(i
= 0; i
< corrected_fields
&& !result
; i
++)
1083 if(mjpeg
->cpus
> 1 || i
== corrected_fields
- 1)
1085 lock_compress_loop(mjpeg
->compressors
[i
]);
1088 append_buffer(&mjpeg
->output_data
,
1089 &mjpeg
->output_size
,
1090 &mjpeg
->output_allocated
,
1091 mjpeg
->compressors
[i
]->output_buffer
,
1092 mjpeg
->compressors
[i
]->output_size
);
1093 if(i
== 0) mjpeg
->output_field2
= mjpeg
->output_size
;
1096 if(corrected_fields
< mjpeg
->fields
)
1098 append_buffer(&mjpeg
->output_data
,
1099 &mjpeg
->output_size
,
1100 &mjpeg
->output_allocated
,
1101 mjpeg
->compressors
[0]->output_buffer
,
1102 mjpeg
->compressors
[0]->output_size
);
1104 //printf("mjpeg_compress 2\n");
1110 int mjpeg_decompress(mjpeg_t
*mjpeg
,
1111 unsigned char *buffer
,
1114 unsigned char **row_pointers
,
1115 unsigned char *y_plane
,
1116 unsigned char *u_plane
,
1117 unsigned char *v_plane
,
1122 int got_first_thread
= 0;
1124 //printf("mjpeg_decompress 1 %d %d\n", buffer_len, input_field2);
1125 if(buffer_len
== 0) return 1;
1126 if(input_field2
== 0 && mjpeg
->fields
> 1) return 1;
1128 //printf("mjpeg_decompress 2\n");
1129 /* Create decompression engines as needed */
1130 for(i
= 0; i
< mjpeg
->fields
; i
++)
1132 if(!mjpeg
->decompressors
[i
])
1134 mjpeg
->decompressors
[i
] = mjpeg_new_decompressor(mjpeg
, i
);
1138 //printf("mjpeg_decompress 3\n");
1139 /* Arm YUV buffers */
1140 mjpeg
->row_argument
= row_pointers
;
1141 mjpeg
->y_argument
= y_plane
;
1142 mjpeg
->u_argument
= u_plane
;
1143 mjpeg
->v_argument
= v_plane
;
1144 mjpeg
->input_data
= buffer
;
1145 mjpeg
->input_size
= buffer_len
;
1146 mjpeg
->input_field2
= input_field2
;
1147 mjpeg
->color_model
= color_model
;
1150 //printf("mjpeg_decompress 4 %02x %02x %d %02x %02x\n", buffer[0], buffer[1], input_field2, buffer[input_field2], buffer[input_field2 + 1]);
1151 /* Start decompressors */
1152 for(i
= 0; i
< mjpeg
->fields
&& !result
; i
++)
1154 unlock_compress_loop(mjpeg
->decompressors
[i
]);
1156 // For dual CPUs, don't want second thread to start until temp data is allocated by the first.
1157 // For single CPUs, don't want two threads running simultaneously
1158 if(mjpeg
->cpus
< 2 || !mjpeg
->temp_data
)
1160 lock_compress_loop(mjpeg
->decompressors
[i
]);
1161 if(i
== 0) got_first_thread
= 1;
1165 //printf("mjpeg_decompress 5\n");
1166 /* Wait for decompressors */
1167 for(i
= 0; i
< mjpeg
->fields
&& !result
; i
++)
1171 if(i
> 0 || !got_first_thread
)
1172 lock_compress_loop(mjpeg
->decompressors
[i
]);
1175 //printf("mjpeg_decompress 6\n");
1177 /* Convert colormodel */
1178 // User colormodel didn't match decompressor
1180 * if(!mjpeg->error &&
1181 * (mjpeg->jpeg_color_model != mjpeg->color_model ||
1182 * mjpeg->coded_w != mjpeg->output_w ||
1183 * mjpeg->coded_h != mjpeg->output_h))
1186 if((mjpeg
->jpeg_color_model
!= mjpeg
->color_model
||
1187 mjpeg
->coded_w
!= mjpeg
->output_w
||
1188 mjpeg
->coded_h
!= mjpeg
->output_h
)
1190 (mjpeg
->temp_data
||
1193 unsigned char *y_in
= mjpeg
->temp_rows
[0][0];
1194 unsigned char *u_in
= mjpeg
->temp_rows
[1][0];
1195 unsigned char *v_in
= mjpeg
->temp_rows
[2][0];
1197 //printf("mjpeg_decompress 7 %p\n", row_pointers);
1198 cmodel_transfer(row_pointers
,
1214 mjpeg
->jpeg_color_model
,
1218 mjpeg
->rowspan
? mjpeg
->rowspan
: mjpeg
->output_w
);
1219 //printf("mjpeg_decompress 8\n");
1225 void mjpeg_set_deinterlace(mjpeg_t
*mjpeg
, int value
)
1227 mjpeg
->deinterlace
= value
;
1230 void mjpeg_set_quality(mjpeg_t
*mjpeg
, int quality
)
1232 mjpeg
->quality
= quality
;
1235 void mjpeg_set_float(mjpeg_t
*mjpeg
, int use_float
)
1237 mjpeg
->use_float
= use_float
;
1240 void mjpeg_set_cpus(mjpeg_t
*mjpeg
, int cpus
)
1245 void mjpeg_set_rowspan(mjpeg_t
*mjpeg
, int rowspan
)
1247 mjpeg
->rowspan
= rowspan
;
1250 int mjpeg_get_fields(mjpeg_t
*mjpeg
)
1252 return mjpeg
->fields
;
1256 mjpeg_t
* mjpeg_new(int w
,
1260 mjpeg_t
*result
= calloc(1, sizeof(mjpeg_t
));
1261 pthread_mutexattr_t mutex_attr
;
1264 result
->output_w
= w
;
1265 result
->output_h
= h
;
1266 result
->fields
= fields
;
1267 result
->color_model
= BC_RGB888
;
1269 result
->quality
= 80;
1270 result
->use_float
= 0;
1272 pthread_mutexattr_init(&mutex_attr
);
1273 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1274 pthread_mutex_init(&(result
->decompress_init
), &mutex_attr
);
1277 // Calculate coded dimensions
1278 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1280 result
->coded_w
= (w
% 16) ? w
+ (16 - (w
% 16)) : w
;
1283 result
->coded_h
= (h
% 16) ? h
+ (16 - (h
% 16)) : h
;
1285 result
->coded_h
= (h
% 32) ? h
+ (32 - (h
% 32)) : h
;
1289 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1296 void mjpeg_delete(mjpeg_t
*mjpeg
)
1299 //printf("mjpeg_delete 1\n");
1300 for(i
= 0; i
< mjpeg
->fields
; i
++)
1302 //printf("mjpeg_delete 2\n");
1303 if(mjpeg
->compressors
[i
]) mjpeg_delete_compressor(mjpeg
->compressors
[i
]);
1304 //printf("mjpeg_delete 3\n");
1305 if(mjpeg
->decompressors
[i
]) mjpeg_delete_decompressor(mjpeg
->decompressors
[i
]);
1306 //printf("mjpeg_delete 4\n");
1308 //printf("mjpeg_delete 5\n");
1309 delete_temps(mjpeg
);
1310 //printf("mjpeg_delete 6\n");
1311 delete_buffer(&mjpeg
->output_data
, &mjpeg
->output_size
, &mjpeg
->output_allocated
);
1312 //printf("mjpeg_delete 7\n");
1314 //printf("mjpeg_delete 2\n");
1318 /* Open up a space to insert a marker */
1319 static void insert_space(unsigned char **buffer
,
1321 long *buffer_allocated
,
1326 // Make sure enough space is available
1327 if(*buffer_allocated
- *buffer_size
< space_len
)
1329 *buffer_allocated
+= space_len
;
1330 *buffer
= realloc(*buffer
, *buffer_allocated
);
1334 for(in
= *buffer_size
- 1, out
= *buffer_size
- 1 + space_len
;
1338 (*buffer
)[out
] = (*buffer
)[in
];
1340 *buffer_size
+= space_len
;
1344 static inline int nextbyte(unsigned char *data
, long *offset
, long length
)
1346 if(length
- *offset
< 1) return 0;
1348 return (unsigned char)data
[*offset
- 1];
1351 static inline int read_int32(unsigned char *data
, long *offset
, long length
)
1353 if(length
- *offset
< 4)
1359 return ((((unsigned int)data
[*offset
- 4]) << 24) |
1360 (((unsigned int)data
[*offset
- 3]) << 16) |
1361 (((unsigned int)data
[*offset
- 2]) << 8) |
1362 (((unsigned int)data
[*offset
- 1])));
1365 static inline int read_int16(unsigned char *data
, long *offset
, long length
)
1367 if(length
- *offset
< 2)
1374 return ((((unsigned int)data
[*offset
- 2]) << 8) |
1375 (((unsigned int)data
[*offset
- 1])));
1378 static inline unsigned char read_char(unsigned char *data
, long *offset
, long length
)
1380 if(length
- *offset
< 1)
1387 return (unsigned char)data
[*offset
- 1];
1390 static inline int next_int16(unsigned char *data
, long *offset
, long length
)
1392 if(length
- *offset
< 2)
1397 return ((((unsigned int)data
[*offset
]) << 8) |
1398 (((unsigned int)data
[*offset
+ 1])));
1401 static inline void write_int32(unsigned char *data
, long *offset
, long length
, unsigned int value
)
1403 if(length
- *offset
< 4)
1410 data
[(*offset
)++] = (unsigned int)(value
& 0xff000000) >> 24;
1411 data
[(*offset
)++] = (unsigned int)(value
& 0xff0000) >> 16;
1412 data
[(*offset
)++] = (unsigned int)(value
& 0xff00) >> 8;
1413 data
[(*offset
)++] = (unsigned char)(value
& 0xff);
1417 static inline void write_char(unsigned char *data
, long *offset
, long length
, unsigned char value
)
1419 if(length
- *offset
< 1)
1425 data
[(*offset
)++] = value
;
1429 static int next_marker(unsigned char *buffer
, long *offset
, long buffer_size
)
1431 int c
, done
= 0; /* 1 - completion 2 - error */
1433 while(*offset
< buffer_size
- 1)
1435 if(buffer
[*offset
] == 0xff && buffer
[*offset
+ 1] != 0xff)
1438 return buffer
[*offset
- 1];
1448 /* Find the next marker after offset and return 0 on success */
1449 static int find_marker(unsigned char *buffer
,
1452 unsigned long marker_type
)
1457 while(!result
&& *offset
< buffer_size
- 1)
1459 int marker
= next_marker(buffer
, offset
, buffer_size
);
1460 if(marker
== (marker_type
& 0xff)) result
= 1;
1470 int padded_field_size
;
1483 int unpadded_field_size
;
1486 #define LML_MARKER_SIZE 0x2c
1487 #define LML_MARKER_TAG 0xffe3
1488 void insert_lml33_markers(unsigned char **buffer
,
1489 long *field2_offset
,
1491 long *buffer_allocated
)
1493 long marker_offset
= -1;
1496 /* Search for existing marker to replace */
1497 // marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);
1499 /* Insert new marker */
1500 if(marker_offset
< 0)
1503 insert_space(buffer
,
1511 static int qt_table_offsets(unsigned char *buffer
,
1522 bzero(header
, sizeof(qt_hdr_t
) * 2);
1524 // Read every marker to get the offsets for the headers
1525 for(field
= 0; field
< 2; field
++)
1531 marker
= next_marker(buffer
,
1540 // The first field may be padded
1543 header
[0].next_offset
=
1544 header
[0].padded_field_size
=
1551 // Quicktime marker already exists. Abort.
1552 if(buffer
[offset
+ 6] == 'm' &&
1553 buffer
[offset
+ 7] == 'j' &&
1554 buffer
[offset
+ 8] == 'p' &&
1555 buffer
[offset
+ 9] == 'a')
1563 if(!header
[field
].quant_offset
)
1565 header
[field
].quant_offset
= offset
- 2;
1567 header
[field
].quant_offset
-= header
[0].next_offset
;
1569 len
= read_int16(buffer
, &offset
, buffer_size
);
1574 if(!header
[field
].huffman_offset
)
1576 header
[field
].huffman_offset
= offset
- 2;
1578 header
[field
].huffman_offset
-= header
[0].next_offset
;
1580 len
= read_int16(buffer
, &offset
, buffer_size
);
1585 if(!header
[field
].image_offset
)
1587 header
[field
].image_offset
= offset
- 2;
1589 header
[field
].image_offset
-= header
[0].next_offset
;
1591 len
= read_int16(buffer
, &offset
, buffer_size
);
1596 header
[field
].scan_offset
= offset
- 2;
1598 header
[field
].scan_offset
-= header
[0].next_offset
;
1599 len
= read_int16(buffer
, &offset
, buffer_size
);
1601 header
[field
].data_offset
= offset
+ len
;
1603 header
[field
].data_offset
-= header
[0].next_offset
;
1610 header
[field
].field_size
=
1611 header
[field
].padded_field_size
=
1612 offset
- header
[0].next_offset
;
1613 header
[field
].next_offset
= 0;
1617 // Often misses second SOI but gets first EOI
1618 // header[0].next_offset =
1619 // header[0].padded_field_size =
1622 //printf("table_offsets M_EOI %d %x\n", field, offset);
1628 // Junk appears between fields
1630 // len = read_int16(buffer, &offset, buffer_size);
1635 if(!done
) offset
+= len
;
1636 if(offset
>= buffer_size
) done
= 1;
1638 //printf("qt_table_offsets 10 %d\n", field);
1644 static void insert_quicktime_marker(unsigned char *buffer
,
1649 write_int32(buffer
, &offset
, buffer_size
, 0xff000000 |
1650 ((unsigned long)M_APP1
<< 16) |
1651 (QUICKTIME_MARKER_SIZE
- 2));
1652 write_int32(buffer
, &offset
, buffer_size
, 0);
1653 write_int32(buffer
, &offset
, buffer_size
, QUICKTIME_JPEG_TAG
);
1654 write_int32(buffer
, &offset
, buffer_size
, header
->field_size
);
1655 write_int32(buffer
, &offset
, buffer_size
, header
->padded_field_size
);
1656 write_int32(buffer
, &offset
, buffer_size
, header
->next_offset
);
1657 write_int32(buffer
, &offset
, buffer_size
, header
->quant_offset
);
1658 write_int32(buffer
, &offset
, buffer_size
, header
->huffman_offset
);
1659 write_int32(buffer
, &offset
, buffer_size
, header
->image_offset
);
1660 write_int32(buffer
, &offset
, buffer_size
, header
->scan_offset
);
1661 write_int32(buffer
, &offset
, buffer_size
, header
->data_offset
);
1665 void mjpeg_insert_quicktime_markers(unsigned char **buffer
,
1667 long *buffer_allocated
,
1669 long *field2_offset
)
1674 *field2_offset
= -1;
1676 if(fields
< 2) return;
1679 // Get offsets for tables in both fields
1680 exists
= qt_table_offsets(*buffer
, *buffer_size
, header
);
1682 // APP1 for quicktime already exists
1685 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1686 // header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1687 //if(*field2_offset == 0)
1688 // fwrite(*buffer, *buffer_size, 1, stdout);
1692 header
[0].field_size
+= QUICKTIME_MARKER_SIZE
;
1693 header
[0].padded_field_size
+= QUICKTIME_MARKER_SIZE
;
1694 header
[0].next_offset
+= QUICKTIME_MARKER_SIZE
;
1695 header
[0].quant_offset
+= QUICKTIME_MARKER_SIZE
;
1696 header
[0].huffman_offset
+= QUICKTIME_MARKER_SIZE
;
1697 header
[0].image_offset
+= QUICKTIME_MARKER_SIZE
;
1698 header
[0].scan_offset
+= QUICKTIME_MARKER_SIZE
;
1699 header
[0].data_offset
+= QUICKTIME_MARKER_SIZE
;
1700 header
[1].field_size
+= QUICKTIME_MARKER_SIZE
;
1701 header
[1].padded_field_size
+= QUICKTIME_MARKER_SIZE
;
1702 header
[1].quant_offset
+= QUICKTIME_MARKER_SIZE
;
1703 header
[1].huffman_offset
+= QUICKTIME_MARKER_SIZE
;
1704 header
[1].image_offset
+= QUICKTIME_MARKER_SIZE
;
1705 header
[1].scan_offset
+= QUICKTIME_MARKER_SIZE
;
1706 header
[1].data_offset
+= QUICKTIME_MARKER_SIZE
;
1707 *field2_offset
= header
[0].next_offset
;
1711 // Insert APP1 marker
1712 insert_space(buffer
,
1716 QUICKTIME_MARKER_SIZE
);
1718 insert_quicktime_marker(*buffer
,
1723 insert_space(buffer
,
1726 header
[0].next_offset
+ 2,
1727 QUICKTIME_MARKER_SIZE
);
1729 header
[1].next_offset
= 0;
1730 insert_quicktime_marker(*buffer
,
1732 header
[0].next_offset
+ 2,
1737 static int avi_table_offsets(unsigned char *buffer
,
1741 int field2
= mjpeg_get_field2(buffer
, buffer_size
);
1743 header
[0].field_number
= 1;
1744 header
[0].field_size
= field2
;
1745 header
[0].unpadded_field_size
= field2
;
1747 header
[1].field_number
= 2;
1748 header
[1].field_size
= buffer_size
- field2
;
1749 header
[1].unpadded_field_size
= buffer_size
- field2
;
1753 static void insert_avi_marker(unsigned char *buffer
,
1758 write_int32(buffer
, &offset
, buffer_size
, 0xff000000 |
1759 ((unsigned long)M_APP0
<< 16) |
1760 (AVI_MARKER_SIZE
- 2));
1761 write_int32(buffer
, &offset
, buffer_size
, QUICKTIME_AVI_TAG
);
1763 // One version of McRoweSoft only allows field polarity while
1764 // another version allows field size.
1765 write_char(buffer
, &offset
, buffer_size
, header
->field_number
);
1766 write_char(buffer
, &offset
, buffer_size
, 0);
1767 write_int32(buffer
, &offset
, buffer_size
, header
->field_size
);
1768 write_int32(buffer
, &offset
, buffer_size
, header
->unpadded_field_size
);
1771 void mjpeg_insert_avi_markers(unsigned char **buffer
,
1773 long *buffer_allocated
,
1775 long *field2_offset
)
1777 avi_hdr_t header
[2];
1779 *field2_offset
= -1;
1782 // Test for existing marker
1783 if(!find_marker(*buffer
, &offset
, *buffer_size
, M_APP0
))
1785 if((*buffer
)[offset
+ 2] == 'A' &&
1786 (*buffer
)[offset
+ 3] == 'V' &&
1787 (*buffer
)[offset
+ 4] == 'I' &&
1788 (*buffer
)[offset
+ 5] == '1')
1793 avi_table_offsets(*buffer
, *buffer_size
, header
);
1795 header
[0].field_size
+= AVI_MARKER_SIZE
;
1796 header
[0].unpadded_field_size
+= AVI_MARKER_SIZE
;
1797 header
[1].field_size
+= AVI_MARKER_SIZE
;
1798 header
[1].unpadded_field_size
+= AVI_MARKER_SIZE
;
1799 *field2_offset
= header
[0].field_size
;
1801 // Insert APP0 marker into field 1
1802 insert_space(buffer
,
1807 insert_avi_marker(*buffer
,
1812 insert_space(buffer
,
1817 insert_avi_marker(*buffer
,
1827 static void read_avi_markers(unsigned char *buffer
,
1832 int marker_count
= 0;
1834 int marker_size
= 0;
1835 while(marker_count
< 2 && offset
< buffer_size
&& !result
)
1837 result
= find_marker(buffer
,
1841 marker_size
= ((unsigned char)buffer
[offset
] << 8) | (unsigned char)buffer
[offset
];
1844 if(!result
&& marker_size
>= 16)
1846 // Marker size, AVI1
1849 header
[marker_count
].field_number
= read_char(buffer
, &offset
, buffer_size
);
1850 read_char(buffer
, &offset
, buffer_size
);
1851 header
[marker_count
].field_size
= read_int32(buffer
, &offset
, buffer_size
);
1852 header
[marker_count
].unpadded_field_size
= read_int32(buffer
, &offset
, buffer_size
);
1859 static void read_quicktime_markers(unsigned char *buffer
,
1864 int marker_count
= 0;
1867 while(marker_count
< 2 && offset
< buffer_size
&& !result
)
1869 result
= find_marker(buffer
,
1877 read_int16(buffer
, &offset
, buffer_size
);
1879 read_int32(buffer
, &offset
, buffer_size
);
1881 read_int32(buffer
, &offset
, buffer_size
);
1883 header
[marker_count
].field_size
= read_int32(buffer
, &offset
, buffer_size
);
1884 header
[marker_count
].padded_field_size
= read_int32(buffer
, &offset
, buffer_size
);
1885 header
[marker_count
].next_offset
= read_int32(buffer
, &offset
, buffer_size
);
1886 header
[marker_count
].quant_offset
= read_int32(buffer
, &offset
, buffer_size
);
1887 header
[marker_count
].huffman_offset
= read_int32(buffer
, &offset
, buffer_size
);
1888 header
[marker_count
].image_offset
= read_int32(buffer
, &offset
, buffer_size
);
1889 header
[marker_count
].scan_offset
= read_int32(buffer
, &offset
, buffer_size
);
1890 header
[marker_count
].data_offset
= read_int32(buffer
, &offset
, buffer_size
);
1894 //printf("read_quicktime_markers 1 %d\n", marker_count);
1897 long mjpeg_get_quicktime_field2(unsigned char *buffer
, long buffer_size
)
1900 bzero(&header
, sizeof(qt_hdr_t
) * 2);
1902 read_quicktime_markers(buffer
, buffer_size
, header
);
1903 return header
[0].next_offset
;
1906 long mjpeg_get_avi_field2(unsigned char *buffer
,
1908 int *field_dominance
)
1910 avi_hdr_t header
[2];
1911 bzero(&header
, sizeof(avi_hdr_t
) * 2);
1912 read_avi_markers(buffer
, buffer_size
, header
);
1914 *field_dominance
= (header
[0].field_number
== 1) ? 1 : 2;
1916 // One version of McRoweSoft only allows field polarity while
1917 // another version allows field size.
1918 if(header
[0].field_size
)
1920 return header
[0].field_size
;
1924 return mjpeg_get_field2(buffer
, buffer_size
);
1929 long mjpeg_get_field2(unsigned char *buffer
, long buffer_size
)
1932 int total_fields
= 0;
1934 long field2_offset
= 0;
1937 for(i
= 0; i
< buffer_size
; i
++)
1939 if(buffer
[i
] == 0xff && buffer
[i
+ 1] == M_SOI
)
1943 if(total_fields
== 2) break;
1948 return field2_offset
;
1951 void mjpeg_video_size(unsigned char *data
, long data_size
, int *w
, int *h
)
1958 *h
= (data
[offset
+ 3] << 8) | (data
[offset
+ 4]);
1959 *w
= (data
[offset
+ 5] << 8) | (data
[offset
+ 6]);