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
]);
1176 /* Convert colormodel */
1177 // User colormodel didn't match decompressor
1179 * if(!mjpeg->error &&
1180 * (mjpeg->jpeg_color_model != mjpeg->color_model ||
1181 * mjpeg->coded_w != mjpeg->output_w ||
1182 * mjpeg->coded_h != mjpeg->output_h))
1185 //printf("mjpeg_decompress 6 %d %d %d %d\n", mjpeg->coded_w, mjpeg->coded_h, mjpeg->output_w, 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];
1198 * printf("mjpeg_decompress 7 in_rowspan=%d out_rowspan=%d\n",
1200 * mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
1202 cmodel_transfer(row_pointers
,
1218 mjpeg
->jpeg_color_model
,
1222 mjpeg
->rowspan
? mjpeg
->rowspan
: mjpeg
->output_w
);
1223 //printf("mjpeg_decompress 8\n");
1229 void mjpeg_set_deinterlace(mjpeg_t
*mjpeg
, int value
)
1231 mjpeg
->deinterlace
= value
;
1234 void mjpeg_set_quality(mjpeg_t
*mjpeg
, int quality
)
1236 mjpeg
->quality
= quality
;
1239 void mjpeg_set_float(mjpeg_t
*mjpeg
, int use_float
)
1241 mjpeg
->use_float
= use_float
;
1244 void mjpeg_set_cpus(mjpeg_t
*mjpeg
, int cpus
)
1249 void mjpeg_set_rowspan(mjpeg_t
*mjpeg
, int rowspan
)
1251 mjpeg
->rowspan
= rowspan
;
1254 int mjpeg_get_fields(mjpeg_t
*mjpeg
)
1256 return mjpeg
->fields
;
1260 mjpeg_t
* mjpeg_new(int w
,
1264 mjpeg_t
*result
= calloc(1, sizeof(mjpeg_t
));
1265 pthread_mutexattr_t mutex_attr
;
1268 result
->output_w
= w
;
1269 result
->output_h
= h
;
1270 result
->fields
= fields
;
1271 result
->color_model
= BC_RGB888
;
1273 result
->quality
= 80;
1274 result
->use_float
= 0;
1276 pthread_mutexattr_init(&mutex_attr
);
1277 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1278 pthread_mutex_init(&(result
->decompress_init
), &mutex_attr
);
1281 // Calculate coded dimensions
1282 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1284 result
->coded_w
= (w
% 16) ? w
+ (16 - (w
% 16)) : w
;
1287 result
->coded_h
= (h
% 16) ? h
+ (16 - (h
% 16)) : h
;
1289 result
->coded_h
= (h
% 32) ? h
+ (32 - (h
% 32)) : h
;
1293 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1300 void mjpeg_delete(mjpeg_t
*mjpeg
)
1303 //printf("mjpeg_delete 1\n");
1304 for(i
= 0; i
< mjpeg
->fields
; i
++)
1306 //printf("mjpeg_delete 2\n");
1307 if(mjpeg
->compressors
[i
]) mjpeg_delete_compressor(mjpeg
->compressors
[i
]);
1308 //printf("mjpeg_delete 3\n");
1309 if(mjpeg
->decompressors
[i
]) mjpeg_delete_decompressor(mjpeg
->decompressors
[i
]);
1310 //printf("mjpeg_delete 4\n");
1312 //printf("mjpeg_delete 5\n");
1313 delete_temps(mjpeg
);
1314 //printf("mjpeg_delete 6\n");
1315 delete_buffer(&mjpeg
->output_data
, &mjpeg
->output_size
, &mjpeg
->output_allocated
);
1316 //printf("mjpeg_delete 7\n");
1318 //printf("mjpeg_delete 2\n");
1322 /* Open up a space to insert a marker */
1323 static void insert_space(unsigned char **buffer
,
1325 long *buffer_allocated
,
1330 // Make sure enough space is available
1331 if(*buffer_allocated
- *buffer_size
< space_len
)
1333 *buffer_allocated
+= space_len
;
1334 *buffer
= realloc(*buffer
, *buffer_allocated
);
1338 for(in
= *buffer_size
- 1, out
= *buffer_size
- 1 + space_len
;
1342 (*buffer
)[out
] = (*buffer
)[in
];
1344 *buffer_size
+= space_len
;
1348 static inline int nextbyte(unsigned char *data
, long *offset
, long length
)
1350 if(length
- *offset
< 1) return 0;
1352 return (unsigned char)data
[*offset
- 1];
1355 static inline int read_int32(unsigned char *data
, long *offset
, long length
)
1357 if(length
- *offset
< 4)
1363 return ((((unsigned int)data
[*offset
- 4]) << 24) |
1364 (((unsigned int)data
[*offset
- 3]) << 16) |
1365 (((unsigned int)data
[*offset
- 2]) << 8) |
1366 (((unsigned int)data
[*offset
- 1])));
1369 static inline int read_int16(unsigned char *data
, long *offset
, long length
)
1371 if(length
- *offset
< 2)
1378 return ((((unsigned int)data
[*offset
- 2]) << 8) |
1379 (((unsigned int)data
[*offset
- 1])));
1382 static inline unsigned char read_char(unsigned char *data
, long *offset
, long length
)
1384 if(length
- *offset
< 1)
1391 return (unsigned char)data
[*offset
- 1];
1394 static inline int next_int16(unsigned char *data
, long *offset
, long length
)
1396 if(length
- *offset
< 2)
1401 return ((((unsigned int)data
[*offset
]) << 8) |
1402 (((unsigned int)data
[*offset
+ 1])));
1405 static inline void write_int32(unsigned char *data
, long *offset
, long length
, unsigned int value
)
1407 if(length
- *offset
< 4)
1414 data
[(*offset
)++] = (unsigned int)(value
& 0xff000000) >> 24;
1415 data
[(*offset
)++] = (unsigned int)(value
& 0xff0000) >> 16;
1416 data
[(*offset
)++] = (unsigned int)(value
& 0xff00) >> 8;
1417 data
[(*offset
)++] = (unsigned char)(value
& 0xff);
1421 static inline void write_char(unsigned char *data
, long *offset
, long length
, unsigned char value
)
1423 if(length
- *offset
< 1)
1429 data
[(*offset
)++] = value
;
1433 static int next_marker(unsigned char *buffer
, long *offset
, long buffer_size
)
1435 int c
, done
= 0; /* 1 - completion 2 - error */
1437 while(*offset
< buffer_size
- 1)
1439 if(buffer
[*offset
] == 0xff && buffer
[*offset
+ 1] != 0xff)
1442 return buffer
[*offset
- 1];
1452 /* Find the next marker after offset and return 0 on success */
1453 static int find_marker(unsigned char *buffer
,
1456 unsigned long marker_type
)
1461 while(!result
&& *offset
< buffer_size
- 1)
1463 int marker
= next_marker(buffer
, offset
, buffer_size
);
1464 if(marker
== (marker_type
& 0xff)) result
= 1;
1474 int padded_field_size
;
1487 int unpadded_field_size
;
1490 #define LML_MARKER_SIZE 0x2c
1491 #define LML_MARKER_TAG 0xffe3
1492 void insert_lml33_markers(unsigned char **buffer
,
1493 long *field2_offset
,
1495 long *buffer_allocated
)
1497 long marker_offset
= -1;
1500 /* Search for existing marker to replace */
1501 // marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);
1503 /* Insert new marker */
1504 if(marker_offset
< 0)
1507 insert_space(buffer
,
1515 static int qt_table_offsets(unsigned char *buffer
,
1526 bzero(header
, sizeof(qt_hdr_t
) * 2);
1528 // Read every marker to get the offsets for the headers
1529 for(field
= 0; field
< 2; field
++)
1535 marker
= next_marker(buffer
,
1544 // The first field may be padded
1547 header
[0].next_offset
=
1548 header
[0].padded_field_size
=
1555 // Quicktime marker already exists. Abort.
1556 if(buffer
[offset
+ 6] == 'm' &&
1557 buffer
[offset
+ 7] == 'j' &&
1558 buffer
[offset
+ 8] == 'p' &&
1559 buffer
[offset
+ 9] == 'a')
1567 if(!header
[field
].quant_offset
)
1569 header
[field
].quant_offset
= offset
- 2;
1571 header
[field
].quant_offset
-= header
[0].next_offset
;
1573 len
= read_int16(buffer
, &offset
, buffer_size
);
1578 if(!header
[field
].huffman_offset
)
1580 header
[field
].huffman_offset
= offset
- 2;
1582 header
[field
].huffman_offset
-= header
[0].next_offset
;
1584 len
= read_int16(buffer
, &offset
, buffer_size
);
1589 if(!header
[field
].image_offset
)
1591 header
[field
].image_offset
= offset
- 2;
1593 header
[field
].image_offset
-= header
[0].next_offset
;
1595 len
= read_int16(buffer
, &offset
, buffer_size
);
1600 header
[field
].scan_offset
= offset
- 2;
1602 header
[field
].scan_offset
-= header
[0].next_offset
;
1603 len
= read_int16(buffer
, &offset
, buffer_size
);
1605 header
[field
].data_offset
= offset
+ len
;
1607 header
[field
].data_offset
-= header
[0].next_offset
;
1614 header
[field
].field_size
=
1615 header
[field
].padded_field_size
=
1616 offset
- header
[0].next_offset
;
1617 header
[field
].next_offset
= 0;
1621 // Often misses second SOI but gets first EOI
1622 // header[0].next_offset =
1623 // header[0].padded_field_size =
1626 //printf("table_offsets M_EOI %d %x\n", field, offset);
1632 // Junk appears between fields
1634 // len = read_int16(buffer, &offset, buffer_size);
1639 if(!done
) offset
+= len
;
1640 if(offset
>= buffer_size
) done
= 1;
1642 //printf("qt_table_offsets 10 %d\n", field);
1648 static void insert_quicktime_marker(unsigned char *buffer
,
1653 write_int32(buffer
, &offset
, buffer_size
, 0xff000000 |
1654 ((unsigned long)M_APP1
<< 16) |
1655 (QUICKTIME_MARKER_SIZE
- 2));
1656 write_int32(buffer
, &offset
, buffer_size
, 0);
1657 write_int32(buffer
, &offset
, buffer_size
, QUICKTIME_JPEG_TAG
);
1658 write_int32(buffer
, &offset
, buffer_size
, header
->field_size
);
1659 write_int32(buffer
, &offset
, buffer_size
, header
->padded_field_size
);
1660 write_int32(buffer
, &offset
, buffer_size
, header
->next_offset
);
1661 write_int32(buffer
, &offset
, buffer_size
, header
->quant_offset
);
1662 write_int32(buffer
, &offset
, buffer_size
, header
->huffman_offset
);
1663 write_int32(buffer
, &offset
, buffer_size
, header
->image_offset
);
1664 write_int32(buffer
, &offset
, buffer_size
, header
->scan_offset
);
1665 write_int32(buffer
, &offset
, buffer_size
, header
->data_offset
);
1669 void mjpeg_insert_quicktime_markers(unsigned char **buffer
,
1671 long *buffer_allocated
,
1673 long *field2_offset
)
1678 *field2_offset
= -1;
1680 if(fields
< 2) return;
1683 // Get offsets for tables in both fields
1684 exists
= qt_table_offsets(*buffer
, *buffer_size
, header
);
1686 // APP1 for quicktime already exists
1689 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1690 // header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1691 //if(*field2_offset == 0)
1692 // fwrite(*buffer, *buffer_size, 1, stdout);
1696 header
[0].field_size
+= QUICKTIME_MARKER_SIZE
;
1697 header
[0].padded_field_size
+= QUICKTIME_MARKER_SIZE
;
1698 header
[0].next_offset
+= QUICKTIME_MARKER_SIZE
;
1699 header
[0].quant_offset
+= QUICKTIME_MARKER_SIZE
;
1700 header
[0].huffman_offset
+= QUICKTIME_MARKER_SIZE
;
1701 header
[0].image_offset
+= QUICKTIME_MARKER_SIZE
;
1702 header
[0].scan_offset
+= QUICKTIME_MARKER_SIZE
;
1703 header
[0].data_offset
+= QUICKTIME_MARKER_SIZE
;
1704 header
[1].field_size
+= QUICKTIME_MARKER_SIZE
;
1705 header
[1].padded_field_size
+= QUICKTIME_MARKER_SIZE
;
1706 header
[1].quant_offset
+= QUICKTIME_MARKER_SIZE
;
1707 header
[1].huffman_offset
+= QUICKTIME_MARKER_SIZE
;
1708 header
[1].image_offset
+= QUICKTIME_MARKER_SIZE
;
1709 header
[1].scan_offset
+= QUICKTIME_MARKER_SIZE
;
1710 header
[1].data_offset
+= QUICKTIME_MARKER_SIZE
;
1711 *field2_offset
= header
[0].next_offset
;
1715 // Insert APP1 marker
1716 insert_space(buffer
,
1720 QUICKTIME_MARKER_SIZE
);
1722 insert_quicktime_marker(*buffer
,
1727 insert_space(buffer
,
1730 header
[0].next_offset
+ 2,
1731 QUICKTIME_MARKER_SIZE
);
1733 header
[1].next_offset
= 0;
1734 insert_quicktime_marker(*buffer
,
1736 header
[0].next_offset
+ 2,
1741 static int avi_table_offsets(unsigned char *buffer
,
1745 int field2
= mjpeg_get_field2(buffer
, buffer_size
);
1747 header
[0].field_number
= 1;
1748 header
[0].field_size
= field2
;
1749 header
[0].unpadded_field_size
= field2
;
1751 header
[1].field_number
= 2;
1752 header
[1].field_size
= buffer_size
- field2
;
1753 header
[1].unpadded_field_size
= buffer_size
- field2
;
1757 static void insert_avi_marker(unsigned char *buffer
,
1762 write_int32(buffer
, &offset
, buffer_size
, 0xff000000 |
1763 ((unsigned long)M_APP0
<< 16) |
1764 (AVI_MARKER_SIZE
- 2));
1765 write_int32(buffer
, &offset
, buffer_size
, QUICKTIME_AVI_TAG
);
1767 // One version of McRoweSoft only allows field polarity while
1768 // another version allows field size.
1769 write_char(buffer
, &offset
, buffer_size
, header
->field_number
);
1770 write_char(buffer
, &offset
, buffer_size
, 0);
1771 write_int32(buffer
, &offset
, buffer_size
, header
->field_size
);
1772 write_int32(buffer
, &offset
, buffer_size
, header
->unpadded_field_size
);
1775 void mjpeg_insert_avi_markers(unsigned char **buffer
,
1777 long *buffer_allocated
,
1779 long *field2_offset
)
1781 avi_hdr_t header
[2];
1783 *field2_offset
= -1;
1786 // Test for existing marker
1787 if(!find_marker(*buffer
, &offset
, *buffer_size
, M_APP0
))
1789 if((*buffer
)[offset
+ 2] == 'A' &&
1790 (*buffer
)[offset
+ 3] == 'V' &&
1791 (*buffer
)[offset
+ 4] == 'I' &&
1792 (*buffer
)[offset
+ 5] == '1')
1797 avi_table_offsets(*buffer
, *buffer_size
, header
);
1799 header
[0].field_size
+= AVI_MARKER_SIZE
;
1800 header
[0].unpadded_field_size
+= AVI_MARKER_SIZE
;
1801 header
[1].field_size
+= AVI_MARKER_SIZE
;
1802 header
[1].unpadded_field_size
+= AVI_MARKER_SIZE
;
1803 *field2_offset
= header
[0].field_size
;
1805 // Insert APP0 marker into field 1
1806 insert_space(buffer
,
1811 insert_avi_marker(*buffer
,
1816 insert_space(buffer
,
1821 insert_avi_marker(*buffer
,
1831 static void read_avi_markers(unsigned char *buffer
,
1836 int marker_count
= 0;
1838 int marker_size
= 0;
1839 while(marker_count
< 2 && offset
< buffer_size
&& !result
)
1841 result
= find_marker(buffer
,
1845 marker_size
= ((unsigned char)buffer
[offset
] << 8) | (unsigned char)buffer
[offset
];
1848 if(!result
&& marker_size
>= 16)
1850 // Marker size, AVI1
1853 header
[marker_count
].field_number
= read_char(buffer
, &offset
, buffer_size
);
1854 read_char(buffer
, &offset
, buffer_size
);
1855 header
[marker_count
].field_size
= read_int32(buffer
, &offset
, buffer_size
);
1856 header
[marker_count
].unpadded_field_size
= read_int32(buffer
, &offset
, buffer_size
);
1863 static void read_quicktime_markers(unsigned char *buffer
,
1868 int marker_count
= 0;
1871 while(marker_count
< 2 && offset
< buffer_size
&& !result
)
1873 result
= find_marker(buffer
,
1881 read_int16(buffer
, &offset
, buffer_size
);
1883 read_int32(buffer
, &offset
, buffer_size
);
1885 read_int32(buffer
, &offset
, buffer_size
);
1887 header
[marker_count
].field_size
= read_int32(buffer
, &offset
, buffer_size
);
1888 header
[marker_count
].padded_field_size
= read_int32(buffer
, &offset
, buffer_size
);
1889 header
[marker_count
].next_offset
= read_int32(buffer
, &offset
, buffer_size
);
1890 header
[marker_count
].quant_offset
= read_int32(buffer
, &offset
, buffer_size
);
1891 header
[marker_count
].huffman_offset
= read_int32(buffer
, &offset
, buffer_size
);
1892 header
[marker_count
].image_offset
= read_int32(buffer
, &offset
, buffer_size
);
1893 header
[marker_count
].scan_offset
= read_int32(buffer
, &offset
, buffer_size
);
1894 header
[marker_count
].data_offset
= read_int32(buffer
, &offset
, buffer_size
);
1898 //printf("read_quicktime_markers 1 %d\n", marker_count);
1901 long mjpeg_get_quicktime_field2(unsigned char *buffer
, long buffer_size
)
1904 bzero(&header
, sizeof(qt_hdr_t
) * 2);
1906 read_quicktime_markers(buffer
, buffer_size
, header
);
1907 return header
[0].next_offset
;
1910 long mjpeg_get_avi_field2(unsigned char *buffer
,
1912 int *field_dominance
)
1914 avi_hdr_t header
[2];
1915 bzero(&header
, sizeof(avi_hdr_t
) * 2);
1916 read_avi_markers(buffer
, buffer_size
, header
);
1918 *field_dominance
= (header
[0].field_number
== 1) ? 1 : 2;
1920 // One version of McRoweSoft only allows field polarity while
1921 // another version allows field size.
1922 if(header
[0].field_size
)
1924 return header
[0].field_size
;
1928 return mjpeg_get_field2(buffer
, buffer_size
);
1933 long mjpeg_get_field2(unsigned char *buffer
, long buffer_size
)
1936 int total_fields
= 0;
1938 long field2_offset
= 0;
1941 for(i
= 0; i
< buffer_size
; i
++)
1943 if(buffer
[i
] == 0xff && buffer
[i
+ 1] == M_SOI
)
1947 if(total_fields
== 2) break;
1952 return field2_offset
;
1955 void mjpeg_video_size(unsigned char *data
, long data_size
, int *w
, int *h
)
1962 *h
= (data
[offset
+ 3] << 8) | (data
[offset
+ 4]);
1963 *w
= (data
[offset
+ 5] << 8) | (data
[offset
+ 6]);