improve resize flash operation, fixup xv grab/ungrab, fixup label updates
[goodguy/history.git] / cinelerra-5.1 / cinelerra / libmjpeg.C
1 /*
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.
6  *
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.
11  *
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
15  * USA
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "bccmodels.h"
22 #include "libmjpeg.h"
23
24 /* JPEG MARKERS */
25 #define   M_SOF0    0xc0
26 #define   M_SOF1    0xc1
27 #define   M_SOF2    0xc2
28 #define   M_SOF3    0xc3
29 #define   M_SOF5    0xc5
30 #define   M_SOF6    0xc6
31 #define   M_SOF7    0xc7
32 #define   M_JPG     0xc8
33 #define   M_SOF9    0xc9
34 #define   M_SOF10   0xca
35 #define   M_SOF11   0xcb
36 #define   M_SOF13   0xcd
37 #define   M_SOF14   0xce
38 #define   M_SOF15   0xcf
39 #define   M_DHT     0xc4
40 #define   M_DAC     0xcc
41 #define   M_RST0    0xd0
42 #define   M_RST1    0xd1
43 #define   M_RST2    0xd2
44 #define   M_RST3    0xd3
45 #define   M_RST4    0xd4
46 #define   M_RST5    0xd5
47 #define   M_RST6    0xd6
48 #define   M_RST7    0xd7
49 #define   M_SOI     0xd8
50 #define   M_EOI     0xd9
51 #define   M_SOS     0xda
52 #define   M_DQT     0xdb
53 #define   M_DNL     0xdc
54 #define   M_DRI     0xdd
55 #define   M_DHP     0xde
56 #define   M_EXP     0xdf
57 #define   M_APP0    0xe0
58 #define   M_APP1    0xe1
59 #define   M_APP2    0xe2
60 #define   M_APP3    0xe3
61 #define   M_APP4    0xe4
62 #define   M_APP5    0xe5
63 #define   M_APP6    0xe6
64 #define   M_APP7    0xe7
65 #define   M_APP8    0xe8
66 #define   M_APP9    0xe9
67 #define   M_APP10   0xea
68 #define   M_APP11   0xeb
69 #define   M_APP12   0xec
70 #define   M_APP13   0xed
71 #define   M_APP14   0xee
72 #define   M_APP15   0xef
73 #define   M_JPG0    0xf0
74 #define   M_JPG13   0xfd
75 #define   M_COM     0xfe
76 #define   M_TEM     0x01
77 #define   M_ERROR   0x100
78
79 #define QUICKTIME_MARKER_SIZE 0x2c
80 #define AVI_MARKER_SIZE 0x12
81 #define QUICKTIME_JPEG_TAG 0x6d6a7067
82 #define QUICKTIME_AVI_TAG 0x41564931
83
84
85 METHODDEF(void) mjpeg_error_exit (j_common_ptr cinfo)
86 {
87 /* cinfo->err really points to a mjpeg_error_mgr struct, so coerce pointer */
88         mjpeg_error_ptr mjpegerr = (mjpeg_error_ptr) cinfo->err;
89
90 /* Always display the message. */
91 /* We could postpone this until after returning, if we chose. */
92         (*cinfo->err->output_message) (cinfo);
93
94 /* Return control to the setjmp point */
95         longjmp(mjpegerr->setjmp_buffer, 1);
96 }
97
98 typedef struct
99 {
100         struct jpeg_destination_mgr pub; /* public fields */
101
102         JOCTET *buffer;         /* Pointer to buffer */
103         mjpeg_compressor *engine;
104 } mjpeg_destination_mgr;
105
106 typedef mjpeg_destination_mgr *mjpeg_dest_ptr;
107
108
109 /*
110  * Initialize destination --- called by jpeg_start_compress
111  * before any data is actually written.
112  */
113
114 METHODDEF(void) init_destination(j_compress_ptr cinfo)
115 {
116         mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
117
118 /* Set the pointer to the preallocated buffer */
119         if(!dest->engine->output_buffer)
120         {
121                 dest->engine->output_buffer = new unsigned char[65536];
122                 memset(dest->engine->output_buffer,0,65536);
123                 dest->engine->output_allocated = 65536;
124         }
125         dest->buffer = dest->engine->output_buffer;
126         dest->pub.next_output_byte = dest->engine->output_buffer;
127         dest->pub.free_in_buffer = dest->engine->output_allocated;
128 }
129
130 /*
131  * Empty the output buffer --- called whenever buffer fills up.
132  *
133  * In typical applications, this should write the entire output buffer
134  * (ignoring the current state of next_output_byte & free_in_buffer),
135  * reset the pointer & count to the start of the buffer, and return TRUE
136  * indicating that the buffer has been dumped.
137  *
138  * In applications that need to be able to suspend compression due to output
139  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
140  * In this situation, the compressor will return to its caller (possibly with
141  * an indication that it has not accepted all the supplied scanlines).  The
142  * application should resume compression after it has made more room in the
143  * output buffer.  Note that there are substantial restrictions on the use of
144  * suspension --- see the documentation.
145  *
146  * When suspending, the compressor will back up to a convenient restart point
147  * (typically the start of the current MCU). next_output_byte & free_in_buffer
148  * indicate where the restart point will be if the current call returns FALSE.
149  * Data beyond this point will be regenerated after resumption, so do not
150  * write it out when emptying the buffer externally.
151  */
152
153 METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
154 {
155 /* Allocate a bigger buffer. */
156         mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
157
158         dest->engine->output_size = dest->engine->output_allocated;
159         dest->engine->output_allocated *= 2;
160         unsigned char *new_buffer = new unsigned char[dest->engine->output_allocated];
161         memcpy(new_buffer, dest->engine->output_buffer, dest->engine->output_size);
162         delete [] dest->engine->output_buffer;
163         dest->engine->output_buffer = new_buffer;
164         dest->buffer = dest->engine->output_buffer;
165         dest->pub.next_output_byte = dest->buffer + dest->engine->output_size;
166         dest->pub.free_in_buffer = dest->engine->output_allocated - dest->engine->output_size;
167
168         return TRUE;
169 }
170
171 /*
172  * Terminate destination --- called by jpeg_finish_compress
173  * after all data has been written.  Usually needs to flush buffer.
174  *
175  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
176  * application must deal with any cleanup that should happen even
177  * for error exit.
178  */
179 METHODDEF(void) term_destination(j_compress_ptr cinfo)
180 {
181 /* Just get the length */
182         mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
183         dest->engine->output_size = dest->engine->output_allocated - dest->pub.free_in_buffer;
184 }
185
186 GLOBAL(void) jpeg_buffer_dest(j_compress_ptr cinfo, mjpeg_compressor *engine)
187 {
188         mjpeg_dest_ptr dest;
189
190 /* The destination object is made permanent so that multiple JPEG images
191  * can be written to the same file without re-executing jpeg_stdio_dest.
192  * This makes it dangerous to use this manager and a different destination
193  * manager serially with the same JPEG object, because their private object
194  * sizes may be different.  Caveat programmer.
195  */
196         if(cinfo->dest == NULL)
197         {
198 /* first time for this JPEG object? */
199         cinfo->dest = (struct jpeg_destination_mgr *)
200                 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
201                                 JPOOL_PERMANENT,
202                                 sizeof(mjpeg_destination_mgr));
203         }
204
205         dest = (mjpeg_dest_ptr)cinfo->dest;
206         dest->pub.init_destination = init_destination;
207         dest->pub.empty_output_buffer = empty_output_buffer;
208         dest->pub.term_destination = term_destination;
209         dest->engine = engine;
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 typedef struct {
226         struct jpeg_source_mgr pub;     /* public fields */
227
228         JOCTET * buffer;                /* start of buffer */
229         int bytes;             /* total size of buffer */
230 } mjpeg_source_mgr;
231
232 typedef mjpeg_source_mgr* mjpeg_src_ptr;
233
234 METHODDEF(void) init_source(j_decompress_ptr cinfo)
235 {
236     //mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
237 }
238
239 METHODDEF(boolean) fill_input_buffer(j_decompress_ptr cinfo)
240 {
241         mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
242
243         src->buffer[0] = (JOCTET)0xFF;
244         src->buffer[1] = (JOCTET)M_EOI;
245         src->pub.next_input_byte = src->buffer;
246         src->pub.bytes_in_buffer = 2;
247
248         return TRUE;
249 }
250
251
252 METHODDEF(void) skip_input_data(j_decompress_ptr cinfo, long num_bytes)
253 {
254         mjpeg_src_ptr src = (mjpeg_src_ptr)cinfo->src;
255
256         src->pub.next_input_byte += (size_t)num_bytes;
257         src->pub.bytes_in_buffer -= (size_t)num_bytes;
258 }
259
260
261 METHODDEF(void) term_source(j_decompress_ptr cinfo)
262 {
263 }
264
265 GLOBAL(void) jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long bytes)
266 {
267         mjpeg_src_ptr src;
268
269 /* first time for this JPEG object? */
270         if(cinfo->src == NULL)
271         {
272         cinfo->src = (struct jpeg_source_mgr*)
273                 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
274                         JPOOL_PERMANENT,
275                                         sizeof(mjpeg_source_mgr));
276         src = (mjpeg_src_ptr)cinfo->src;
277         }
278
279         src = (mjpeg_src_ptr)cinfo->src;
280         src->pub.init_source = init_source;
281         src->pub.fill_input_buffer = fill_input_buffer;
282         src->pub.skip_input_data = skip_input_data;
283         src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
284         src->pub.term_source = term_source;
285         src->pub.bytes_in_buffer = bytes;
286         src->pub.next_input_byte = buffer;
287         src->buffer = buffer;
288         src->bytes = bytes;
289 }
290
291 /* JPEG DHT Segment for YCrCb omitted from MJPEG data */
292 static
293 unsigned char jpeg_odml_dht[0x1a4] = {
294     0xff, 0xc4, 0x01, 0xa2,
295
296     0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
298
299     0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
300     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
301
302     0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
303     0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
304     0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
305     0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
306     0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
307     0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
308     0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
309     0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
310     0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
311     0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
312     0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
313     0xf9, 0xfa,
314
315     0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
316     0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
317     0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
318     0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
319     0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
320     0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
321     0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
322     0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
323     0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
324     0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
325     0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
326     0xf9, 0xfa
327 };
328
329
330 /*
331  * Parse the DHT table.
332  * This code comes from jpeg6b (jdmarker.c).
333  */
334 static
335 int jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
336               JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
337 {
338     unsigned int length = (dht[2] << 8) + dht[3] - 2;
339     unsigned int pos = 4;
340     unsigned int count, i;
341     int index;
342
343     JHUFF_TBL **hufftbl;
344     unsigned char bits[17];
345     unsigned char huffval[256];
346
347     while (length > 16)
348     {
349        bits[0] = 0;
350        index = dht[pos++];
351        count = 0;
352        for (i = 1; i <= 16; ++i)
353        {
354            bits[i] = dht[pos++];
355            count += bits[i];
356        }
357        length -= 17;
358
359        if (count > 256 || count > length)
360            return -1;
361
362        for (i = 0; i < count; ++i)
363            huffval[i] = dht[pos++];
364        length -= count;
365
366        if (index & 0x10)
367        {
368            index -= 0x10;
369            hufftbl = &ac_tables[index];
370        }
371        else
372            hufftbl = &dc_tables[index];
373
374        if (index < 0 || index >= NUM_HUFF_TBLS)
375            return -1;
376
377        if (*hufftbl == NULL)
378            *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
379        if (*hufftbl == NULL)
380            return -1;
381
382        memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
383        memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
384     }
385
386     if (length != 0)
387        return -1;
388
389     return 0;
390 }
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406 static void reset_buffer(unsigned char **buffer, long *size, long *allocated)
407 {
408         *size = 0;
409 }
410
411 static void delete_buffer(unsigned char **buffer, long *size, long *allocated)
412 {
413         if(*buffer)
414         {
415                 delete [] *buffer;
416                 *size = 0;
417                 *allocated = 0;
418         }
419 }
420
421 static void append_buffer(unsigned char **buffer,
422         long *size,
423         long *allocated,
424         unsigned char *data,
425         long data_size)
426 {
427         if(!*buffer)
428         {
429                 *buffer = new unsigned char[65536];
430                 memset(*buffer,0,65536);
431                 *size = 0;
432                 *allocated = 65536;
433         }
434
435         if(*size + data_size + 0x100 > *allocated)
436         {
437                 *allocated = *size + data_size + 0x100;
438                 unsigned char *new_buffer = new unsigned char[*allocated];
439                 memcpy(new_buffer, *buffer, *size);
440                 delete [] *buffer;
441                 *buffer = new_buffer;
442         }
443
444         memcpy(*buffer + *size, data, data_size);
445         *size += data_size;
446 }
447
448 static void allocate_temps(mjpeg_t *mjpeg)
449 {
450         int i;
451
452         if(!mjpeg->temp_data)
453     {
454         switch(mjpeg->jpeg_color_model)
455         {
456             case BC_YUV422P:
457 //printf("allocate_temps 1\n");
458                     mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h * 2];
459                     mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
460                     mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h];
461                     mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h];
462                     for(i = 0; i < mjpeg->coded_h; i++)
463                     {
464                             mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
465                             mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w / 2;
466                             mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w / 2 * mjpeg->coded_h + i * mjpeg->coded_w / 2;
467                     }
468                 break;
469
470             case BC_YUV444P:
471                     mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h * 3];
472                     mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
473                     mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h];
474                     mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h];
475                     if(mjpeg->greyscale)
476                                 {
477                                         memset(mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h,
478                                                 0x80,
479                                                 mjpeg->coded_w * mjpeg->coded_h * 2);
480                                 }
481                                 for(i = 0; i < mjpeg->coded_h; i++)
482                     {
483                             mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
484                             mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
485                             mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
486                     }
487                 break;
488
489             case BC_YUV420P:
490                     mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h / 2];
491                     mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
492                     mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h / 2];
493                     mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h / 2];
494                     for(i = 0; i < mjpeg->coded_h; i++)
495                     {
496                             mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
497                             if(i < mjpeg->coded_h / 2)
498                             {
499                                     mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * (mjpeg->coded_w / 2);
500                                     mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + (mjpeg->coded_h / 2) * (mjpeg->coded_w / 2) + i * (mjpeg->coded_w / 2);
501                             }
502                     }
503                 break;
504         }
505     }
506 }
507
508 static int get_input_row(mjpeg_t *mjpeg, mjpeg_compressor *compressor, int i)
509 {
510         int input_row;
511         if(mjpeg->fields > 1)
512                 input_row = i * 2 + compressor->instance;
513         else
514                 input_row = i;
515         if(input_row >= mjpeg->coded_h) input_row = mjpeg->coded_h - 1;
516         return input_row;
517 }
518
519 // Get pointers to rows for the JPEG compressor
520 static void get_rows(mjpeg_t *mjpeg, mjpeg_compressor *compressor)
521 {
522         int i;
523     switch(mjpeg->jpeg_color_model)
524     {
525                 case BC_YUV444P:
526                 {
527                         if(!compressor->rows[0])
528                         {
529                                 compressor->rows[0] = new unsigned char*[compressor->coded_field_h];
530                                 compressor->rows[1] = new unsigned char*[compressor->coded_field_h];
531                                 compressor->rows[2] = new unsigned char*[compressor->coded_field_h];
532                         }
533
534 // User colormodel matches jpeg colormodel
535                         if(mjpeg->color_model == BC_YUV444P &&
536                                 mjpeg->output_w == mjpeg->coded_w &&
537                                 mjpeg->output_h == mjpeg->coded_h)
538                         {
539                                 for(i = 0; i < compressor->coded_field_h; i++)
540                                 {
541                                         int input_row = get_input_row(mjpeg, compressor, i);
542                                         compressor->rows[0][i] = mjpeg->y_argument +
543                                                 mjpeg->coded_w * input_row;
544                                         compressor->rows[1][i] = mjpeg->u_argument +
545                                                 mjpeg->coded_w * input_row;
546                                         compressor->rows[2][i] = mjpeg->v_argument +
547                                                 mjpeg->coded_w * input_row;
548                                 }
549                         }
550                         else
551                         {
552                                 for(i = 0; i < compressor->coded_field_h; i++)
553                                 {
554                                         int input_row = get_input_row(mjpeg, compressor, i);
555                                         compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
556                                         compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
557                                         compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
558                                 }
559                         }
560                         break;
561                 }
562
563                 case BC_YUV422P:
564                 {
565                         if(!compressor->rows[0])
566                         {
567                                 compressor->rows[0] = new unsigned char*[compressor->coded_field_h];
568                                 compressor->rows[1] = new unsigned char*[compressor->coded_field_h];
569                                 compressor->rows[2] = new unsigned char*[compressor->coded_field_h];
570                         }
571
572 // User colormodel matches jpeg colormodel
573                         if(mjpeg->color_model == BC_YUV422P &&
574                                 mjpeg->output_w == mjpeg->coded_w &&
575                                 mjpeg->output_h == mjpeg->coded_h)
576                         {
577                                 for(i = 0; i < compressor->coded_field_h; i++)
578                                 {
579                                         int input_row = get_input_row(mjpeg, compressor, i);
580                                         compressor->rows[0][i] = mjpeg->y_argument +
581                                                 mjpeg->coded_w * input_row;
582                                         compressor->rows[1][i] = mjpeg->u_argument +
583                                                 (mjpeg->coded_w / 2) * input_row;
584                                         compressor->rows[2][i] = mjpeg->v_argument +
585                                                 (mjpeg->coded_w / 2) * input_row;
586                                 }
587                         }
588                         else
589                         {
590                                 for(i = 0; i < compressor->coded_field_h; i++)
591                                 {
592                                         int input_row = get_input_row(mjpeg, compressor, i);
593                                         compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
594                                         compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
595                                         compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
596                                 }
597                         }
598                         break;
599                 }
600
601                 case BC_YUV420P:
602                 {
603                         if(!compressor->rows[0])
604                         {
605                                 compressor->rows[0] = new unsigned char*[mjpeg->coded_h];
606                                 compressor->rows[1] = new unsigned char*[mjpeg->coded_h / 2];
607                                 compressor->rows[2] = new unsigned char*[mjpeg->coded_h / 2];
608                         }
609
610 // User colormodel matches jpeg colormodel
611                         if(mjpeg->color_model == BC_YUV420P &&
612                                 mjpeg->output_w == mjpeg->coded_w &&
613                                 mjpeg->output_h == mjpeg->coded_h)
614                         {
615                                 for(i = 0; i < compressor->coded_field_h; i++)
616                                 {
617                                         int input_row = get_input_row(mjpeg, compressor, i);
618                                         compressor->rows[0][i] = mjpeg->y_argument +
619                                                 mjpeg->coded_w * input_row;
620                         if(i < compressor->coded_field_h / 2)
621                         {
622                                         compressor->rows[1][i] = mjpeg->u_argument +
623                                                 (mjpeg->coded_w / 2) * input_row;
624                                         compressor->rows[2][i] = mjpeg->v_argument +
625                                                 (mjpeg->coded_w / 2) * input_row;
626                         }
627                                 }
628                         }
629                         else
630                         {
631                                 for(i = 0; i < compressor->coded_field_h; i++)
632                                 {
633                                         int input_row = get_input_row(mjpeg, compressor, i);
634                                         compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
635                         if(i < compressor->coded_field_h / 2)
636                         {
637                                         compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
638                                         compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
639                         }
640                                 }
641                         }
642                         break;
643                 }
644         }
645 }
646
647 static void delete_rows(mjpeg_compressor *compressor)
648 {
649         if(compressor->rows[0])
650         {
651                 delete [] compressor->rows[0];
652                 delete [] compressor->rows[1];
653                 delete [] compressor->rows[2];
654         }
655 }
656
657 /* replacement routine to suppress decompress warnings */
658 static void mjpeg_emit_message(j_common_ptr cinfo, int msg_level)
659 {
660   struct jpeg_error_mgr * err = cinfo->err;
661   if (msg_level < 0) {
662     err->num_warnings++;
663     if(err->trace_level >= 3)
664       (*err->output_message) (cinfo);
665   } else {
666     if (err->trace_level >= msg_level)
667       (*err->output_message) (cinfo);
668   }
669 }
670
671 static void new_jpeg_objects(mjpeg_compressor *engine)
672 {
673         engine->jpeg_decompress.err = jpeg_std_error(&(engine->jpeg_error.pub));
674         engine->jpeg_error.pub.error_exit = mjpeg_error_exit;
675         engine->jpeg_error.pub.emit_message = mjpeg_emit_message;
676 /* Ideally the error handler would be set here but it must be called in a thread */
677         jpeg_create_decompress(&(engine->jpeg_decompress));
678         engine->jpeg_decompress.raw_data_out = TRUE;
679 #if JPEG_LIB_VERSION >= 70
680         engine->jpeg_decompress.do_fancy_upsampling = FALSE;
681 #endif
682         engine->jpeg_decompress.dct_method = JDCT_IFAST;
683 }
684
685 static void delete_jpeg_objects(mjpeg_compressor *engine)
686 {
687         jpeg_destroy_decompress(&(engine->jpeg_decompress));
688 }
689
690
691
692 static void unlock_compress_loop(mjpeg_compressor *engine)
693 {
694         pthread_mutex_unlock(&(engine->input_lock));
695 }
696
697 static void lock_compress_loop(mjpeg_compressor *engine)
698 {
699         pthread_mutex_lock(&(engine->output_lock));
700 }
701
702 // Make temp rows for compressor
703 static void get_mcu_rows(mjpeg_t *mjpeg,
704         mjpeg_compressor *engine,
705         int start_row)
706 {
707         int i, j, scanline;
708         for(i = 0; i < 3; i++)
709         {
710                 for(j = 0; j < 16; j++)
711                 {
712                         if(i > 0 && j >= 8 && mjpeg->jpeg_color_model == BC_YUV420P) break;
713
714                         scanline = start_row;
715                         if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) scanline /= 2;
716                         scanline += j;
717                         if(scanline >= engine->coded_field_h) scanline = engine->coded_field_h - 1;
718                         engine->mcu_rows[i][j] = engine->rows[i][scanline];
719                 }
720         }
721 }
722
723
724 static void decompress_field(mjpeg_compressor *engine)
725 {
726         mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
727         long buffer_offset = engine->instance * mjpeg->input_field2;
728         unsigned char *buffer = mjpeg->input_data + buffer_offset;
729         long buffer_size;
730
731 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
732         if(engine->instance == 0 && mjpeg->fields > 1)
733                 buffer_size = mjpeg->input_field2 - buffer_offset;
734         else
735                 buffer_size = mjpeg->input_size - buffer_offset;
736
737         mjpeg->error = 0;
738
739         if(setjmp(engine->jpeg_error.setjmp_buffer))
740         {
741 /* If we get here, the JPEG code has signaled an error. */
742 printf("decompress_field %d\n", __LINE__);
743                 delete_jpeg_objects(engine);
744 printf("decompress_field %d\n", __LINE__);
745                 new_jpeg_objects(engine);
746 printf("decompress_field %d\n", __LINE__);
747                 mjpeg->error = 1;
748 printf("decompress_field %d\n", __LINE__);
749                 goto finish;
750         }
751
752 //printf("decompress_field 2\n");
753         jpeg_buffer_src(&engine->jpeg_decompress,
754                 buffer,
755                 buffer_size);
756         jpeg_read_header(&engine->jpeg_decompress, TRUE);
757
758         if ( engine->jpeg_decompress.ac_huff_tbl_ptrs[0] == NULL &&
759              engine->jpeg_decompress.ac_huff_tbl_ptrs[1] == NULL &&
760              engine->jpeg_decompress.dc_huff_tbl_ptrs[0] == NULL &&
761              engine->jpeg_decompress.dc_huff_tbl_ptrs[1] == NULL )
762                 jpeg_load_dht(  &engine->jpeg_decompress,
763                                 jpeg_odml_dht,
764                                 engine->jpeg_decompress.ac_huff_tbl_ptrs,
765                                 engine->jpeg_decompress.dc_huff_tbl_ptrs );
766 // Reset by jpeg_read_header
767         engine->jpeg_decompress.raw_data_out = TRUE;
768 #if JPEG_LIB_VERSION >= 70
769         engine->jpeg_decompress.do_fancy_upsampling = FALSE;
770 #endif
771         jpeg_start_decompress(&engine->jpeg_decompress);
772
773 // Generate colormodel from jpeg sampling
774         if( engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
775             engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
776                 mjpeg->jpeg_color_model = BC_YUV420P;
777         else if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 1 &&
778             engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
779                 mjpeg->jpeg_color_model = BC_YUV422P;
780         else
781                 mjpeg->jpeg_color_model = BC_YUV444P;
782
783         if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE)
784                 mjpeg->greyscale = 1;
785
786 //printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor);
787 // Must be here because the color model isn't known until now
788         pthread_mutex_lock(&(mjpeg->decompress_init));
789         allocate_temps(mjpeg);
790         pthread_mutex_unlock(&(mjpeg->decompress_init));
791         get_rows(mjpeg, engine);
792
793 //printf("decompress_field 30\n");
794
795         while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
796         {
797                 get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
798                 jpeg_read_raw_data(&engine->jpeg_decompress,
799                         engine->mcu_rows,
800                         engine->coded_field_h);
801         }
802         jpeg_finish_decompress(&engine->jpeg_decompress);
803
804 //printf("decompress_field 40\n");
805
806 finish:
807         ;
808 }
809
810 void mjpeg_decompress_loop(mjpeg_compressor *engine)
811 {
812         while(!engine->done)
813         {
814                 pthread_mutex_lock(&engine->input_lock);
815                 if(!engine->done)
816                 {
817                         decompress_field(engine);
818                 }
819                 pthread_mutex_unlock(&(engine->output_lock));
820         }
821 }
822
823
824 static void compress_field(mjpeg_compressor *engine)
825 {
826         mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
827
828 //printf("compress_field 1\n");
829         get_rows(mjpeg, engine);
830         reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
831         jpeg_buffer_dest(&engine->jpeg_compress, engine);
832
833
834         engine->jpeg_compress.raw_data_in = TRUE;
835 #if JPEG_LIB_VERSION >= 70
836         engine->jpeg_compress.do_fancy_downsampling = FALSE;
837 #endif
838         jpeg_start_compress(&engine->jpeg_compress, TRUE);
839
840         while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
841         {
842                 get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
843
844                 jpeg_write_raw_data(&engine->jpeg_compress,
845                         engine->mcu_rows,
846                         engine->coded_field_h);
847         }
848         jpeg_finish_compress(&engine->jpeg_compress);
849 //printf("compress_field 2\n");
850 }
851
852
853 void mjpeg_compress_loop(mjpeg_compressor *engine)
854 {
855         while(!engine->done)
856         {
857                 pthread_mutex_lock(&engine->input_lock);
858                 if(!engine->done)
859                 {
860                         compress_field(engine);
861                 }
862                 pthread_mutex_unlock(&engine->output_lock);
863         }
864 }
865
866 static void delete_temps(mjpeg_t *mjpeg)
867 {
868         if(mjpeg->temp_data)
869     {
870             delete [] mjpeg->temp_data;
871             delete [] mjpeg->temp_rows[0];
872             delete [] mjpeg->temp_rows[1];
873             delete [] mjpeg->temp_rows[2];
874                 mjpeg->temp_data = 0;
875         }
876 }
877
878 mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
879 {
880         mjpeg_compressor *result = new mjpeg_compressor();
881         memset(result, 0, sizeof(mjpeg_compressor));
882         pthread_attr_t  attr;
883         pthread_mutexattr_t mutex_attr;
884
885         result->mjpeg = mjpeg;
886         result->instance = instance;
887         new_jpeg_objects(result);
888         result->field_h = mjpeg->output_h / mjpeg->fields;
889         result->coded_field_h = (result->field_h % 16) ?
890                 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
891
892         result->mcu_rows[0] = new unsigned char *[16];
893         result->mcu_rows[1] = new unsigned char *[16];
894         result->mcu_rows[2] = new unsigned char *[16];
895
896         pthread_mutexattr_init(&mutex_attr);
897 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
898         pthread_mutex_init(&(result->input_lock), &mutex_attr);
899         pthread_mutex_lock(&(result->input_lock));
900         pthread_mutex_init(&(result->output_lock), &mutex_attr);
901         pthread_mutex_lock(&(result->output_lock));
902
903         pthread_attr_init(&attr);
904         pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_decompress_loop, result);
905
906         return result;
907 }
908
909 void mjpeg_delete_decompressor(mjpeg_compressor *engine)
910 {
911         engine->done = 1;
912         pthread_mutex_unlock(&(engine->input_lock));
913         pthread_join(engine->tid, 0);
914         pthread_mutex_destroy(&(engine->input_lock));
915         pthread_mutex_destroy(&(engine->output_lock));
916         jpeg_destroy_decompress(&(engine->jpeg_decompress));
917         delete_rows(engine);
918         delete [] engine->mcu_rows[0];
919         delete [] engine->mcu_rows[1];
920         delete [] engine->mcu_rows[2];
921         delete engine;
922 }
923
924 mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
925 {
926         pthread_attr_t  attr;
927         pthread_mutexattr_t mutex_attr;
928         mjpeg_compressor *result = new mjpeg_compressor();
929         memset(result, 0, sizeof(mjpeg_compressor));
930
931         result->field_h = mjpeg->output_h / mjpeg->fields;
932         result->coded_field_h = (result->field_h % 16) ?
933                 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
934         result->mjpeg = mjpeg;
935         result->instance = instance;
936         result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
937         jpeg_create_compress(&(result->jpeg_compress));
938         result->jpeg_compress.image_width = mjpeg->output_w;
939         result->jpeg_compress.image_height = result->field_h;
940         result->jpeg_compress.input_components = 3;
941         result->jpeg_compress.in_color_space = JCS_RGB;
942         jpeg_set_defaults(&(result->jpeg_compress));
943         result->jpeg_compress.input_components = 3;
944         result->jpeg_compress.in_color_space = JCS_RGB;
945         jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
946
947         if(mjpeg->use_float)
948                 result->jpeg_compress.dct_method = JDCT_FLOAT;
949         else
950                 result->jpeg_compress.dct_method = JDCT_IFAST;
951 //              result->jpeg_compress.dct_method = JDCT_ISLOW;
952
953 /* Fix sampling */
954         switch(mjpeg->fields)
955     {
956         case 1:
957                 mjpeg->jpeg_color_model = BC_YUV420P;
958                     result->jpeg_compress.comp_info[0].h_samp_factor = 2;
959                     result->jpeg_compress.comp_info[0].v_samp_factor = 2;
960                     result->jpeg_compress.comp_info[1].h_samp_factor = 1;
961                     result->jpeg_compress.comp_info[1].v_samp_factor = 1;
962                     result->jpeg_compress.comp_info[2].h_samp_factor = 1;
963                     result->jpeg_compress.comp_info[2].v_samp_factor = 1;
964                 break;
965         case 2:
966                 mjpeg->jpeg_color_model = BC_YUV422P;
967                     result->jpeg_compress.comp_info[0].h_samp_factor = 2;
968                     result->jpeg_compress.comp_info[0].v_samp_factor = 1;
969                     result->jpeg_compress.comp_info[1].h_samp_factor = 1;
970                     result->jpeg_compress.comp_info[1].v_samp_factor = 1;
971                     result->jpeg_compress.comp_info[2].h_samp_factor = 1;
972                     result->jpeg_compress.comp_info[2].v_samp_factor = 1;
973                 break;
974     }
975     allocate_temps(mjpeg);
976
977         result->mcu_rows[0] = new unsigned char *[16];
978         result->mcu_rows[1] = new unsigned char *[16];
979         result->mcu_rows[2] = new unsigned char *[16];
980
981         pthread_mutexattr_init(&mutex_attr);
982 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
983         pthread_mutex_init(&(result->input_lock), &mutex_attr);
984         pthread_mutex_lock(&(result->input_lock));
985         pthread_mutex_init(&(result->output_lock), &mutex_attr);
986         pthread_mutex_lock(&(result->output_lock));
987
988         pthread_attr_init(&attr);
989         pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_compress_loop, result);
990         return result;
991 }
992
993
994 void mjpeg_delete_compressor(mjpeg_compressor *engine)
995 {
996         engine->done = 1;
997         pthread_mutex_unlock(&(engine->input_lock));
998         pthread_join(engine->tid, 0);
999         pthread_mutex_destroy(&(engine->input_lock));
1000         pthread_mutex_destroy(&(engine->output_lock));
1001         jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
1002         if(engine->output_buffer) delete [] engine->output_buffer;
1003         delete_rows(engine);
1004         delete [] engine->mcu_rows[0];
1005         delete [] engine->mcu_rows[1];
1006         delete [] engine->mcu_rows[2];
1007         delete engine;
1008 }
1009
1010 unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
1011 {
1012         return mjpeg->output_data;
1013 }
1014
1015 long mjpeg_output_field2(mjpeg_t *mjpeg)
1016 {
1017         return mjpeg->output_field2;
1018 }
1019
1020 long mjpeg_output_size(mjpeg_t *mjpeg)
1021 {
1022         return mjpeg->output_size;
1023 }
1024
1025 long mjpeg_output_allocated(mjpeg_t *mjpeg)
1026 {
1027         return mjpeg->output_allocated;
1028 }
1029
1030 void mjpeg_set_output_size(mjpeg_t *mjpeg, long output_size)
1031 {
1032         mjpeg->output_size = output_size;
1033 }
1034
1035
1036 int mjpeg_compress(mjpeg_t *mjpeg,
1037         unsigned char **row_pointers,
1038         unsigned char *y_plane,
1039         unsigned char *u_plane,
1040         unsigned char *v_plane,
1041         int color_model,
1042         int cpus)
1043 {
1044         int i, result = 0;
1045         int corrected_fields = mjpeg->fields;
1046         mjpeg->color_model = color_model;
1047         mjpeg->cpus = cpus;
1048
1049 //printf("mjpeg_compress 1 %d\n", color_model);
1050 /* Reset output buffer */
1051         reset_buffer(&mjpeg->output_data,
1052                 &mjpeg->output_size,
1053                 &mjpeg->output_allocated);
1054
1055 /* Create compression engines as needed */
1056         for(i = 0; i < mjpeg->fields; i++)
1057         {
1058                 if(!mjpeg->compressors[i])
1059                 {
1060                         mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
1061                 }
1062         }
1063
1064 /* Arm YUV buffers */
1065         mjpeg->row_argument = row_pointers;
1066         mjpeg->y_argument = y_plane;
1067         mjpeg->u_argument = u_plane;
1068         mjpeg->v_argument = v_plane;
1069 // User colormodel doesn't match encoder colormodel
1070 // Copy to interlacing buffer first
1071         if(mjpeg->color_model != mjpeg->jpeg_color_model ||
1072                 mjpeg->output_w != mjpeg->coded_w ||
1073                 mjpeg->output_h != mjpeg->coded_h)
1074         {
1075 /*
1076  * printf("mjpeg_compress %d %d %d %d\n",
1077  * mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_h);
1078  */
1079                 BC_CModels::transfer(0,
1080                         row_pointers,
1081                         mjpeg->temp_rows[0][0],
1082                         mjpeg->temp_rows[1][0],
1083                         mjpeg->temp_rows[2][0],
1084                         y_plane,
1085                         u_plane,
1086                         v_plane,
1087                         0,
1088                         0,
1089                         mjpeg->output_w,
1090                         mjpeg->output_h,
1091                         0,
1092                         0,
1093                         mjpeg->output_w,
1094                         mjpeg->output_h,
1095                         mjpeg->color_model,
1096                         mjpeg->jpeg_color_model,
1097                         0,
1098                         mjpeg->output_w,
1099                         mjpeg->coded_w);
1100         }
1101
1102 /* Start the compressors on the image fields */
1103         if(mjpeg->deinterlace) corrected_fields = 1;
1104         for(i = 0; i < corrected_fields && !result; i++)
1105         {
1106                 unlock_compress_loop(mjpeg->compressors[i]);
1107
1108                 if(mjpeg->cpus < 2 && i < corrected_fields - 1)
1109                 {
1110                         lock_compress_loop(mjpeg->compressors[i]);
1111                 }
1112         }
1113
1114 /* Wait for the compressors and store in master output */
1115         for(i = 0; i < corrected_fields && !result; i++)
1116         {
1117                 if(mjpeg->cpus > 1 || i == corrected_fields - 1)
1118                 {
1119                         lock_compress_loop(mjpeg->compressors[i]);
1120                 }
1121
1122                 append_buffer(&mjpeg->output_data,
1123                         &mjpeg->output_size,
1124                         &mjpeg->output_allocated,
1125                         mjpeg->compressors[i]->output_buffer,
1126                         mjpeg->compressors[i]->output_size);
1127                 if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
1128         }
1129
1130         if(corrected_fields < mjpeg->fields)
1131         {
1132                 append_buffer(&mjpeg->output_data,
1133                         &mjpeg->output_size,
1134                         &mjpeg->output_allocated,
1135                         mjpeg->compressors[0]->output_buffer,
1136                         mjpeg->compressors[0]->output_size);
1137         }
1138 //printf("mjpeg_compress 2\n");
1139         return 0;
1140 }
1141
1142
1143
1144 int mjpeg_decompress(mjpeg_t *mjpeg,
1145         unsigned char *buffer,
1146         long buffer_len,
1147         long input_field2,
1148         unsigned char **row_pointers,
1149         unsigned char *y_plane,
1150         unsigned char *u_plane,
1151         unsigned char *v_plane,
1152         int color_model,
1153         int cpus)
1154 {
1155         int i, result = 0;
1156         int got_first_thread = 0;
1157
1158 //printf("mjpeg_decompress 1 %d\n", color_model);
1159         if(buffer_len == 0) return 1;
1160         if(input_field2 == 0 && mjpeg->fields > 1) return 1;
1161
1162 //printf("mjpeg_decompress 2\n");
1163 /* Create decompression engines as needed */
1164         for(i = 0; i < mjpeg->fields; i++)
1165         {
1166                 if(!mjpeg->decompressors[i])
1167                 {
1168                         mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
1169                 }
1170         }
1171
1172 //printf("mjpeg_decompress 3\n");
1173 /* Arm YUV buffers */
1174         mjpeg->row_argument = row_pointers;
1175         mjpeg->y_argument = y_plane;
1176         mjpeg->u_argument = u_plane;
1177         mjpeg->v_argument = v_plane;
1178         mjpeg->input_data = buffer;
1179         mjpeg->input_size = buffer_len;
1180         mjpeg->input_field2 = input_field2;
1181         mjpeg->color_model = color_model;
1182         mjpeg->cpus = cpus;
1183
1184 //printf("mjpeg_decompress 4 %02x %02x %d %02x %02x\n", buffer[0], buffer[1], input_field2, buffer[input_field2], buffer[input_field2 + 1]);
1185 /* Start decompressors */
1186         for(i = 0; i < mjpeg->fields && !result; i++)
1187         {
1188 //printf("mjpeg_decompress 5\n");
1189                 unlock_compress_loop(mjpeg->decompressors[i]);
1190 //printf("mjpeg_decompress 6\n");
1191
1192 // For dual CPUs, don't want second thread to start until temp data is allocated by the first.
1193 // For single CPUs, don't want two threads running simultaneously
1194                 if(mjpeg->cpus < 2 || !mjpeg->temp_data)
1195                 {
1196 //printf("mjpeg_decompress 7\n");
1197                         lock_compress_loop(mjpeg->decompressors[i]);
1198 //printf("mjpeg_decompress 8\n");
1199                         if(i == 0) got_first_thread = 1;
1200                 }
1201         }
1202
1203 //printf("mjpeg_decompress 10\n");
1204 /* Wait for decompressors */
1205         for(i = 0; i < mjpeg->fields && !result; i++)
1206         {
1207                 if(mjpeg->cpus > 1)
1208                 {
1209                         if(i > 0 || !got_first_thread)
1210                                 lock_compress_loop(mjpeg->decompressors[i]);
1211                 }
1212         }
1213
1214 /* Convert colormodel */
1215 // User colormodel didn't match decompressor
1216 /*
1217  *      if(!mjpeg->error &&
1218  *              (mjpeg->jpeg_color_model != mjpeg->color_model ||
1219  *              mjpeg->coded_w != mjpeg->output_w ||
1220  *              mjpeg->coded_h != mjpeg->output_h))
1221  */
1222
1223 //printf("mjpeg_decompress 6 %d %d %d %d\n", mjpeg->coded_w, mjpeg->coded_h, mjpeg->output_w, mjpeg->output_h);
1224         if((mjpeg->jpeg_color_model != mjpeg->color_model ||
1225                 mjpeg->coded_w != mjpeg->output_w ||
1226                 mjpeg->coded_h != mjpeg->output_h)
1227                 &&
1228                 (mjpeg->temp_data ||
1229                 !mjpeg->error))
1230         {
1231                 unsigned char *y_in = mjpeg->temp_rows[0][0];
1232                 unsigned char *u_in = mjpeg->temp_rows[1][0];
1233                 unsigned char *v_in = mjpeg->temp_rows[2][0];
1234
1235
1236 /*
1237  * printf("mjpeg_decompress 7 coded_w=%d coded_h=%d output_w=%d output_h=%d out_rowspan=%d in_colormodel=%d out_colormodel=%d\n",
1238  * mjpeg->coded_w,
1239  * mjpeg->coded_h,
1240  * mjpeg->output_w,
1241  * mjpeg->output_h,
1242  * mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w,
1243  * mjpeg->jpeg_color_model,
1244  * mjpeg->color_model);
1245  */
1246
1247                 BC_CModels::transfer(row_pointers,
1248                         0,
1249                         y_plane,
1250                         u_plane,
1251                         v_plane,
1252                         y_in,
1253                         u_in,
1254                         v_in,
1255                         0,
1256                         0,
1257                         mjpeg->output_w,
1258                         mjpeg->output_h,
1259                         0,
1260                         0,
1261                         mjpeg->output_w,
1262                         mjpeg->output_h,
1263                         mjpeg->jpeg_color_model,
1264                         mjpeg->color_model,
1265                         0,
1266                         mjpeg->coded_w,
1267                         mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
1268 //printf("mjpeg_decompress 8\n");
1269         }
1270         return 0;
1271 }
1272
1273
1274 void mjpeg_set_deinterlace(mjpeg_t *mjpeg, int value)
1275 {
1276         mjpeg->deinterlace = value;
1277 }
1278
1279 void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
1280 {
1281         mjpeg->quality = quality;
1282 }
1283
1284 void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
1285 {
1286         mjpeg->use_float = use_float;
1287 }
1288
1289 void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
1290 {
1291         mjpeg->cpus = cpus;
1292 }
1293
1294 void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan)
1295 {
1296         mjpeg->rowspan = rowspan;
1297 }
1298
1299 int mjpeg_get_fields(mjpeg_t *mjpeg)
1300 {
1301         return mjpeg->fields;
1302 }
1303
1304
1305 mjpeg_t* mjpeg_new(int w,
1306         int h,
1307         int fields)
1308 {
1309         mjpeg_t *result = new mjpeg_t();
1310         memset(result, 0, sizeof(*result));
1311         pthread_mutexattr_t mutex_attr;
1312
1313         result->output_w = w;
1314         result->output_h = h;
1315         result->fields = fields;
1316         result->color_model = BC_RGB888;
1317         result->cpus = 1;
1318         result->quality = 80;
1319         result->use_float = 0;
1320
1321         pthread_mutexattr_init(&mutex_attr);
1322 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1323         pthread_mutex_init(&(result->decompress_init), &mutex_attr);
1324
1325
1326 // Calculate coded dimensions
1327 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1328
1329         result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
1330
1331         if(fields == 1)
1332                 result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
1333         else
1334                 result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
1335
1336
1337
1338 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1339         return result;
1340 }
1341
1342
1343
1344
1345 void mjpeg_delete(mjpeg_t *mjpeg)
1346 {
1347         int i;
1348 //printf("mjpeg_delete 1\n");
1349         for(i = 0; i < mjpeg->fields; i++)
1350         {
1351 //printf("mjpeg_delete 2\n");
1352                 if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
1353 //printf("mjpeg_delete 3\n");
1354                 if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
1355 //printf("mjpeg_delete 4\n");
1356         }
1357 //printf("mjpeg_delete 5\n");
1358         delete_temps(mjpeg);
1359 //printf("mjpeg_delete 6\n");
1360         delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
1361 //printf("mjpeg_delete 7\n");
1362         delete mjpeg;
1363 //printf("mjpeg_delete 2\n");
1364 }
1365
1366
1367 /* Open up a space to insert a marker */
1368 static void insert_space(unsigned char **buffer,
1369         long *buffer_size,
1370         long *buffer_allocated,
1371         long space_start,
1372         long space_len)
1373 {
1374         int in, out;
1375 // Make sure enough space is available
1376         if(*buffer_allocated - *buffer_size < space_len)
1377         {
1378                 *buffer_allocated += space_len;
1379                 unsigned char *new_buffer = new unsigned char[*buffer_allocated];
1380                 memcpy(new_buffer, *buffer, *buffer_size);
1381                 delete [] *buffer;
1382                 *buffer = new_buffer;
1383         }
1384
1385 // Shift data back
1386         for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
1387                 in >= space_start;
1388                 in--, out--)
1389         {
1390                 (*buffer)[out] = (*buffer)[in];
1391         }
1392         *buffer_size += space_len;
1393 }
1394
1395
1396 static inline int nextbyte(unsigned char *data, long *offset, long length)
1397 {
1398         if(length - *offset < 1) return 0;
1399         *offset += 1;
1400         return (unsigned char)data[*offset - 1];
1401 }
1402
1403 static inline int read_int32(unsigned char *data, long *offset, long length)
1404 {
1405         if(length - *offset < 4)
1406         {
1407                 *offset = length;
1408                 return 0;
1409         }
1410         *offset += 4;
1411         return ((((unsigned int)data[*offset - 4]) << 24) |
1412                 (((unsigned int)data[*offset - 3]) << 16) |
1413                 (((unsigned int)data[*offset - 2]) << 8) |
1414                 (((unsigned int)data[*offset - 1])));
1415 }
1416
1417 static inline int read_int16(unsigned char *data, long *offset, long length)
1418 {
1419         if(length - *offset < 2)
1420         {
1421                 *offset = length;
1422                 return 0;
1423         }
1424
1425         *offset += 2;
1426         return ((((unsigned int)data[*offset - 2]) << 8) |
1427                 (((unsigned int)data[*offset - 1])));
1428 }
1429
1430 static inline unsigned char read_char(unsigned char *data, long *offset, long length)
1431 {
1432         if(length - *offset < 1)
1433         {
1434                 *offset = length;
1435                 return 0;
1436         }
1437
1438         *offset += 1;
1439         return (unsigned char)data[*offset - 1];
1440 }
1441
1442 static inline int next_int16(unsigned char *data, long *offset, long length)
1443 {
1444         if(length - *offset < 2)
1445         {
1446                 return 0;
1447         }
1448
1449         return ((((unsigned int)data[*offset]) << 8) |
1450                 (((unsigned int)data[*offset + 1])));
1451 }
1452
1453 static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
1454 {
1455         if(length - *offset < 4)
1456         {
1457                 *offset = length;
1458                 return;
1459         }
1460
1461
1462         data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
1463         data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
1464         data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
1465         data[(*offset)++] = (unsigned char)(value & 0xff);
1466         return;
1467 }
1468
1469 static inline void write_char(unsigned char *data, long *offset, long length, unsigned char value)
1470 {
1471         if(length - *offset < 1)
1472         {
1473                 *offset = length;
1474                 return;
1475         }
1476
1477         data[(*offset)++] = value;
1478         return;
1479 }
1480
1481 static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
1482 {
1483         while(*offset < buffer_size - 1) {
1484                 if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff) {
1485                         (*offset) += 2;
1486                         return buffer[*offset - 1];
1487                 }
1488                 (*offset)++;
1489         }
1490         return 0;
1491 }
1492
1493 /* Find the next marker after offset and return 0 on success */
1494 static int find_marker(unsigned char *buffer,
1495         long *offset,
1496         long buffer_size,
1497         unsigned long marker_type)
1498 {
1499         long result = 0;
1500
1501         while(!result && *offset < buffer_size - 1)
1502         {
1503                 unsigned int marker = next_marker(buffer, offset, buffer_size);
1504                 if(marker == (marker_type & 0xff)) result = 1;
1505         }
1506
1507         return !result;
1508 }
1509
1510
1511 typedef struct
1512 {
1513         int field_size;
1514         int padded_field_size;
1515         int next_offset;
1516         int quant_offset;
1517         int huffman_offset;
1518         int image_offset;
1519         int scan_offset;
1520         int data_offset;
1521 } qt_hdr_t;
1522
1523 typedef struct
1524 {
1525         int field_number;
1526         int field_size;
1527         int unpadded_field_size;
1528 } avi_hdr_t;
1529
1530 #define LML_MARKER_SIZE 0x2c
1531 #define LML_MARKER_TAG 0xffe3
1532 void insert_lml33_markers(unsigned char **buffer,
1533         long *field2_offset,
1534         long *buffer_size,
1535         long *buffer_allocated)
1536 {
1537         long marker_offset = -1;
1538
1539 /* Search for existing marker to replace */
1540 //      marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);
1541
1542 /* Insert new marker */
1543         if(marker_offset < 0)
1544         {
1545                 marker_offset = 2;
1546                 insert_space(buffer,
1547                         buffer_size,
1548                         buffer_allocated,
1549                         2,
1550                         LML_MARKER_SIZE);
1551         }
1552 }
1553
1554 static int qt_table_offsets(unsigned char *buffer,
1555         long buffer_size,
1556         qt_hdr_t *header)
1557 {
1558         int done = 0;
1559         long offset = 0;
1560         int marker = 0;
1561         int field = 0;
1562         int len;
1563         int result = 0;
1564
1565         bzero(header, sizeof(qt_hdr_t) * 2);
1566
1567 // Read every marker to get the offsets for the headers
1568         for(field = 0; field < 2; field++)
1569         {
1570                 done = 0;
1571
1572                 while(!done)
1573                 {
1574                         marker = next_marker(buffer,
1575                                 &offset,
1576                                 buffer_size);
1577
1578                         len = 0;
1579
1580                         switch(marker)
1581                         {
1582                                 case M_SOI:
1583 // The first field may be padded
1584                                         if(field > 0)
1585                                         {
1586                                                 header[0].next_offset =
1587                                                         header[0].padded_field_size =
1588                                                         offset - 2;
1589                                         }
1590                                         len = 0;
1591                                         break;
1592
1593                                 case M_APP1:
1594 // Quicktime marker already exists.  Abort.
1595                                         if(buffer[offset + 6] == 'm' &&
1596                                                 buffer[offset + 7] == 'j' &&
1597                                                 buffer[offset + 8] == 'p' &&
1598                                                 buffer[offset + 9] == 'a')
1599                                         {
1600                                                 result = 1;
1601                                                 done = 1;
1602                                         }
1603                                         break;
1604
1605                                 case M_DQT:
1606                                         if(!header[field].quant_offset)
1607                                         {
1608                                                 header[field].quant_offset = offset - 2;
1609                                                 if(field > 0)
1610                                                         header[field].quant_offset -= header[0].next_offset;
1611                                         }
1612                                         len = read_int16(buffer, &offset, buffer_size);
1613                                         len -= 2;
1614                                         break;
1615
1616                                 case M_DHT:
1617                                         if(!header[field].huffman_offset)
1618                                         {
1619                                                 header[field].huffman_offset = offset - 2;
1620                                                 if(field > 0)
1621                                                         header[field].huffman_offset -= header[0].next_offset;
1622                                         }
1623                                         len = read_int16(buffer, &offset, buffer_size);
1624                                         len -= 2;
1625                                         break;
1626
1627                                 case M_SOF0:
1628                                         if(!header[field].image_offset)
1629                                         {
1630                                                 header[field].image_offset = offset - 2;
1631                                                 if(field > 0)
1632                                                         header[field].image_offset -= header[0].next_offset;
1633                                         }
1634                                         len = read_int16(buffer, &offset, buffer_size);
1635                                         len -= 2;
1636                                         break;
1637
1638                                 case M_SOS:
1639                                         header[field].scan_offset = offset - 2;
1640                                         if(field > 0)
1641                                                 header[field].scan_offset -= header[0].next_offset;
1642                                         len = read_int16(buffer, &offset, buffer_size);
1643                                         len -= 2;
1644                                         header[field].data_offset = offset + len;
1645                                         if(field > 0)
1646                                                 header[field].data_offset -= header[0].next_offset;
1647                                         break;
1648
1649 //                              case 0:
1650                                 case M_EOI:
1651                                         if(field > 0)
1652                                         {
1653                                                 header[field].field_size =
1654                                                         header[field].padded_field_size =
1655                                                         offset - header[0].next_offset;
1656                                                 header[field].next_offset = 0;
1657                                         }
1658                                         else
1659                                         {
1660 // Often misses second SOI but gets first EOI
1661 //                                              header[0].next_offset =
1662 //                                                      header[0].padded_field_size =
1663 //                                                      offset;
1664                                         }
1665 //printf("table_offsets M_EOI %d %x\n", field, offset);
1666                                         done = 1;
1667                                         len = 0;
1668                                         break;
1669
1670                                 default:
1671 // Junk appears between fields
1672                                         len = 0;
1673 //                                      len = read_int16(buffer, &offset, buffer_size);
1674 //                                      len -= 2;
1675                                         break;
1676                         }
1677
1678                         if(!done) offset += len;
1679                         if(offset >= buffer_size) done = 1;
1680                 }
1681 //printf("qt_table_offsets 10 %d\n", field);
1682         }
1683
1684         return result;
1685 }
1686
1687 static void insert_quicktime_marker(unsigned char *buffer,
1688         long buffer_size,
1689         long offset,
1690         qt_hdr_t *header)
1691 {
1692         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1693                         ((unsigned long)M_APP1 << 16) |
1694                         (QUICKTIME_MARKER_SIZE - 2));
1695         write_int32(buffer, &offset, buffer_size, 0);
1696         write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1697         write_int32(buffer, &offset, buffer_size, header->field_size);
1698         write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1699         write_int32(buffer, &offset, buffer_size, header->next_offset);
1700         write_int32(buffer, &offset, buffer_size, header->quant_offset);
1701         write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1702         write_int32(buffer, &offset, buffer_size, header->image_offset);
1703         write_int32(buffer, &offset, buffer_size, header->scan_offset);
1704         write_int32(buffer, &offset, buffer_size, header->data_offset);
1705 }
1706
1707
1708 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1709         long *buffer_size,
1710         long *buffer_allocated,
1711         int fields,
1712         long *field2_offset)
1713 {
1714         qt_hdr_t header[2];
1715         int exists = 0;
1716         *field2_offset = -1;
1717
1718         if(fields < 2) return;
1719
1720
1721 // Get offsets for tables in both fields
1722         exists = qt_table_offsets(*buffer, *buffer_size, header);
1723
1724 // APP1 for quicktime already exists
1725         if(exists) return;
1726
1727 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1728 //      header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1729 //if(*field2_offset == 0)
1730 //      fwrite(*buffer, *buffer_size, 1, stdout);
1731
1732
1733
1734         header[0].field_size += QUICKTIME_MARKER_SIZE;
1735         header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1736         header[0].next_offset += QUICKTIME_MARKER_SIZE;
1737         header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1738         header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1739         header[0].image_offset += QUICKTIME_MARKER_SIZE;
1740         header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1741         header[0].data_offset += QUICKTIME_MARKER_SIZE;
1742         header[1].field_size += QUICKTIME_MARKER_SIZE;
1743         header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1744         header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1745         header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1746         header[1].image_offset += QUICKTIME_MARKER_SIZE;
1747         header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1748         header[1].data_offset += QUICKTIME_MARKER_SIZE;
1749         *field2_offset = header[0].next_offset;
1750
1751
1752
1753 // Insert APP1 marker
1754         insert_space(buffer,
1755                 buffer_size,
1756                 buffer_allocated,
1757                 2,
1758                 QUICKTIME_MARKER_SIZE);
1759
1760         insert_quicktime_marker(*buffer,
1761                 *buffer_size,
1762                 2,
1763                 &header[0]);
1764
1765         insert_space(buffer,
1766                 buffer_size,
1767                 buffer_allocated,
1768                 header[0].next_offset + 2,
1769                 QUICKTIME_MARKER_SIZE);
1770
1771         header[1].next_offset = 0;
1772         insert_quicktime_marker(*buffer,
1773                 *buffer_size,
1774                 header[0].next_offset + 2,
1775                 &header[1]);
1776 }
1777
1778
1779 static int avi_table_offsets(unsigned char *buffer,
1780         long buffer_size,
1781         avi_hdr_t *header)
1782 {
1783         int field2 = mjpeg_get_field2(buffer, buffer_size);
1784
1785         header[0].field_number = 1;
1786         header[0].field_size = field2;
1787         header[0].unpadded_field_size = field2;
1788
1789         header[1].field_number = 2;
1790         header[1].field_size = buffer_size - field2;
1791         header[1].unpadded_field_size = buffer_size - field2;
1792         return 0;
1793 }
1794
1795 static void insert_avi_marker(unsigned char *buffer,
1796         long buffer_size,
1797         long offset,
1798         avi_hdr_t *header)
1799 {
1800         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1801                         ((unsigned long)M_APP0 << 16) |
1802                         (AVI_MARKER_SIZE - 2));
1803         write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1804
1805 // One version of McRoweSoft only allows field polarity while
1806 // another version allows field size.
1807         write_char(buffer, &offset, buffer_size, header->field_number);
1808         write_char(buffer, &offset, buffer_size, 0);
1809         write_int32(buffer, &offset, buffer_size, header->field_size);
1810         write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1811 }
1812
1813 void mjpeg_insert_avi_markers(unsigned char **buffer,
1814         long *buffer_size,
1815         long *buffer_allocated,
1816         int fields,
1817         long *field2_offset)
1818 {
1819         avi_hdr_t header[2];
1820         long offset = 0;
1821         *field2_offset = -1;
1822
1823
1824 // Test for existing marker
1825         if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1826         {
1827                 if((*buffer)[offset + 2] == 'A' &&
1828                         (*buffer)[offset + 3] == 'V' &&
1829                         (*buffer)[offset + 4] == 'I' &&
1830                         (*buffer)[offset + 5] == '1')
1831                         return;
1832         }
1833
1834
1835         avi_table_offsets(*buffer, *buffer_size, header);
1836
1837         header[0].field_size += AVI_MARKER_SIZE;
1838         header[0].unpadded_field_size += AVI_MARKER_SIZE;
1839         header[1].field_size += AVI_MARKER_SIZE;
1840         header[1].unpadded_field_size += AVI_MARKER_SIZE;
1841         *field2_offset = header[0].field_size;
1842
1843 // Insert APP0 marker into field 1
1844         insert_space(buffer,
1845                 buffer_size,
1846                 buffer_allocated,
1847                 2,
1848                 AVI_MARKER_SIZE);
1849         insert_avi_marker(*buffer,
1850                 *buffer_size,
1851                 2,
1852                 &header[0]);
1853
1854         insert_space(buffer,
1855                 buffer_size,
1856                 buffer_allocated,
1857                 *field2_offset + 2,
1858                 AVI_MARKER_SIZE);
1859         insert_avi_marker(*buffer,
1860                 *buffer_size,
1861                 *field2_offset + 2,
1862                 &header[1]);
1863
1864
1865
1866 }
1867
1868
1869 static void read_avi_markers(unsigned char *buffer,
1870         long buffer_size,
1871         avi_hdr_t *header)
1872 {
1873         long offset = 0;
1874         int marker_count = 0;
1875         int result = 0;
1876         int marker_size = 0;
1877         while(marker_count < 2 && offset < buffer_size && !result)
1878         {
1879                 result = find_marker(buffer,
1880                         &offset,
1881                         buffer_size,
1882                         M_APP0);
1883                 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1884
1885
1886                 if(!result && marker_size >= 16)
1887                 {
1888 // Marker size, AVI1
1889                         offset += 6;
1890 // field polarity
1891                         header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1892                         read_char(buffer, &offset, buffer_size);
1893                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1894                         header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1895                         marker_count++;
1896                 }
1897         }
1898 }
1899
1900
1901 static void read_quicktime_markers(unsigned char *buffer,
1902         long buffer_size,
1903         qt_hdr_t *header)
1904 {
1905         long offset = 0;
1906         int marker_count = 0;
1907         int result = 0;
1908
1909         while(marker_count < 2 && offset < buffer_size && !result)
1910         {
1911                 result = find_marker(buffer,
1912                         &offset,
1913                         buffer_size,
1914                         M_APP1);
1915
1916                 if(!result)
1917                 {
1918 // Marker size
1919                         read_int16(buffer, &offset, buffer_size);
1920 // Zero
1921                         read_int32(buffer, &offset, buffer_size);
1922 // MJPA
1923                         read_int32(buffer, &offset, buffer_size);
1924 // Information
1925                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1926                         header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1927                         header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1928                         header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1929                         header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1930                         header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1931                         header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1932                         header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1933                         marker_count++;
1934                 }
1935         }
1936 //printf("read_quicktime_markers 1 %d\n", marker_count);
1937 }
1938
1939 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1940 {
1941         qt_hdr_t header[2];
1942         bzero(&header, sizeof(qt_hdr_t) * 2);
1943
1944         read_quicktime_markers(buffer, buffer_size, header);
1945         return header[0].next_offset;
1946 }
1947
1948 long mjpeg_get_avi_field2(unsigned char *buffer,
1949         long buffer_size,
1950         int *field_dominance)
1951 {
1952         avi_hdr_t header[2];
1953         bzero(&header, sizeof(avi_hdr_t) * 2);
1954         read_avi_markers(buffer, buffer_size, header);
1955
1956         *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1957
1958 // One version of McRoweSoft only allows field polarity while
1959 // another version allows field size.
1960         if(header[0].field_size)
1961         {
1962                 return header[0].field_size;
1963         }
1964         else
1965         {
1966                 return mjpeg_get_field2(buffer, buffer_size);
1967         }
1968         return 0;
1969 }
1970
1971 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1972 {
1973         int total_fields = 0;
1974         long field2_offset = 0;
1975         int i;
1976
1977         for(i = 0; i < buffer_size; i++)
1978         {
1979                 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1980                 {
1981                         total_fields++;
1982                         field2_offset = i;
1983                         if(total_fields == 2) break;
1984                 }
1985         }
1986         return field2_offset;
1987 }
1988
1989 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1990 {
1991           long offset = 0;
1992           find_marker(data,
1993                           &offset,
1994                           data_size,
1995                           M_SOF0);
1996           *h = (data[offset + 3] << 8) | (data[offset + 4]);
1997           *w = (data[offset + 5] << 8) | (data[offset + 6]);
1998 }
1999
2000