Reported by Fedora team for gcc-13 and Andrew created patch here
[goodguy/cinelerra.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, lastline;
708         for(i = 0; i < 3; i++)
709         {
710                 for(j = 0; j < 16; j++)
711                 {
712                         scanline = start_row;
713                         lastline = engine->coded_field_h;
714                         if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) {
715                                 lastline /= 2;  scanline /= 2;
716                         }
717                         scanline += j;
718                         if(scanline >= lastline) scanline = lastline - 1;
719                         engine->mcu_rows[i][j] = engine->rows[i][scanline];
720                 }
721         }
722 }
723
724
725 static void decompress_field(mjpeg_compressor *engine)
726 {
727         mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
728         long buffer_offset = engine->instance * mjpeg->input_field2;
729         unsigned char *buffer = mjpeg->input_data + buffer_offset;
730         long buffer_size;
731
732 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
733         if(engine->instance == 0 && mjpeg->fields > 1)
734                 buffer_size = mjpeg->input_field2 - buffer_offset;
735         else
736                 buffer_size = mjpeg->input_size - buffer_offset;
737
738         mjpeg->error = 0;
739
740         if(setjmp(engine->jpeg_error.setjmp_buffer))
741         {
742 /* If we get here, the JPEG code has signaled an error. */
743 printf("decompress_field %d\n", __LINE__);
744                 delete_jpeg_objects(engine);
745 printf("decompress_field %d\n", __LINE__);
746                 new_jpeg_objects(engine);
747 printf("decompress_field %d\n", __LINE__);
748                 mjpeg->error = 1;
749 printf("decompress_field %d\n", __LINE__);
750                 goto finish;
751         }
752
753 //printf("decompress_field 2\n");
754         jpeg_buffer_src(&engine->jpeg_decompress,
755                 buffer,
756                 buffer_size);
757         jpeg_read_header(&engine->jpeg_decompress, TRUE);
758
759         if ( engine->jpeg_decompress.ac_huff_tbl_ptrs[0] == NULL &&
760              engine->jpeg_decompress.ac_huff_tbl_ptrs[1] == NULL &&
761              engine->jpeg_decompress.dc_huff_tbl_ptrs[0] == NULL &&
762              engine->jpeg_decompress.dc_huff_tbl_ptrs[1] == NULL )
763                 jpeg_load_dht(  &engine->jpeg_decompress,
764                                 jpeg_odml_dht,
765                                 engine->jpeg_decompress.ac_huff_tbl_ptrs,
766                                 engine->jpeg_decompress.dc_huff_tbl_ptrs );
767 // Reset by jpeg_read_header
768         engine->jpeg_decompress.raw_data_out = TRUE;
769 #if JPEG_LIB_VERSION >= 70
770         engine->jpeg_decompress.do_fancy_upsampling = FALSE;
771 #endif
772         jpeg_start_decompress(&engine->jpeg_decompress);
773
774 // Generate colormodel from jpeg sampling
775         if( engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
776             engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
777                 mjpeg->jpeg_color_model = BC_YUV420P;
778         else if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 1 &&
779             engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
780                 mjpeg->jpeg_color_model = BC_YUV422P;
781         else
782                 mjpeg->jpeg_color_model = BC_YUV444P;
783
784         if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE)
785                 mjpeg->greyscale = 1;
786
787 //printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor);
788 // Must be here because the color model isn't known until now
789         pthread_mutex_lock(&(mjpeg->decompress_init));
790         allocate_temps(mjpeg);
791         pthread_mutex_unlock(&(mjpeg->decompress_init));
792         get_rows(mjpeg, engine);
793
794 //printf("decompress_field 30\n");
795
796         while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
797         {
798                 get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
799                 jpeg_read_raw_data(&engine->jpeg_decompress,
800                         engine->mcu_rows,
801                         engine->coded_field_h);
802         }
803         jpeg_finish_decompress(&engine->jpeg_decompress);
804
805 //printf("decompress_field 40\n");
806
807 finish:
808         ;
809 }
810
811 void mjpeg_decompress_loop(mjpeg_compressor *engine)
812 {
813         while(!engine->done)
814         {
815                 pthread_mutex_lock(&engine->input_lock);
816                 if(!engine->done)
817                 {
818                         decompress_field(engine);
819                 }
820                 pthread_mutex_unlock(&(engine->output_lock));
821         }
822 }
823
824
825 static void compress_field(mjpeg_compressor *engine)
826 {
827         mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
828
829 //printf("compress_field 1\n");
830         get_rows(mjpeg, engine);
831         reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
832         jpeg_buffer_dest(&engine->jpeg_compress, engine);
833
834
835         engine->jpeg_compress.raw_data_in = TRUE;
836 #if JPEG_LIB_VERSION >= 70
837         engine->jpeg_compress.do_fancy_downsampling = FALSE;
838 #endif
839         jpeg_start_compress(&engine->jpeg_compress, TRUE);
840
841         while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
842         {
843                 get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
844
845                 jpeg_write_raw_data(&engine->jpeg_compress,
846                         engine->mcu_rows,
847                         engine->coded_field_h);
848         }
849         jpeg_finish_compress(&engine->jpeg_compress);
850 //printf("compress_field 2\n");
851 }
852
853
854 void mjpeg_compress_loop(mjpeg_compressor *engine)
855 {
856         while(!engine->done)
857         {
858                 pthread_mutex_lock(&engine->input_lock);
859                 if(!engine->done)
860                 {
861                         compress_field(engine);
862                 }
863                 pthread_mutex_unlock(&engine->output_lock);
864         }
865 }
866
867 static void delete_temps(mjpeg_t *mjpeg)
868 {
869         if(mjpeg->temp_data)
870     {
871             delete [] mjpeg->temp_data;
872             delete [] mjpeg->temp_rows[0];
873             delete [] mjpeg->temp_rows[1];
874             delete [] mjpeg->temp_rows[2];
875                 mjpeg->temp_data = 0;
876         }
877 }
878
879 mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
880 {
881         mjpeg_compressor *result = new mjpeg_compressor();
882         memset(result, 0, sizeof(mjpeg_compressor));
883         pthread_attr_t  attr;
884         pthread_mutexattr_t mutex_attr;
885
886         result->mjpeg = mjpeg;
887         result->instance = instance;
888         new_jpeg_objects(result);
889         result->field_h = mjpeg->output_h / mjpeg->fields;
890         result->coded_field_h = (result->field_h % 16) ?
891                 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
892
893         result->mcu_rows[0] = new unsigned char *[16];
894         result->mcu_rows[1] = new unsigned char *[16];
895         result->mcu_rows[2] = new unsigned char *[16];
896
897         pthread_mutexattr_init(&mutex_attr);
898 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
899         pthread_mutex_init(&(result->input_lock), &mutex_attr);
900         pthread_mutex_lock(&(result->input_lock));
901         pthread_mutex_init(&(result->output_lock), &mutex_attr);
902         pthread_mutex_lock(&(result->output_lock));
903
904         pthread_attr_init(&attr);
905         pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_decompress_loop, result);
906
907         return result;
908 }
909
910 void mjpeg_delete_decompressor(mjpeg_compressor *engine)
911 {
912         engine->done = 1;
913         pthread_mutex_unlock(&(engine->input_lock));
914         pthread_join(engine->tid, 0);
915         pthread_mutex_destroy(&(engine->input_lock));
916         pthread_mutex_destroy(&(engine->output_lock));
917         jpeg_destroy_decompress(&(engine->jpeg_decompress));
918         delete_rows(engine);
919         delete [] engine->mcu_rows[0];
920         delete [] engine->mcu_rows[1];
921         delete [] engine->mcu_rows[2];
922         delete engine;
923 }
924
925 mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
926 {
927         pthread_attr_t  attr;
928         pthread_mutexattr_t mutex_attr;
929         mjpeg_compressor *result = new mjpeg_compressor();
930         memset(result, 0, sizeof(mjpeg_compressor));
931
932         result->field_h = mjpeg->output_h / mjpeg->fields;
933         result->coded_field_h = (result->field_h % 16) ?
934                 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
935         result->mjpeg = mjpeg;
936         result->instance = instance;
937         result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
938         jpeg_create_compress(&(result->jpeg_compress));
939         result->jpeg_compress.image_width = mjpeg->output_w;
940         result->jpeg_compress.image_height = result->field_h;
941         result->jpeg_compress.input_components = 3;
942         result->jpeg_compress.in_color_space = JCS_RGB;
943         jpeg_set_defaults(&(result->jpeg_compress));
944         result->jpeg_compress.input_components = 3;
945         result->jpeg_compress.in_color_space = JCS_RGB;
946         jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
947
948         if(mjpeg->use_float)
949                 result->jpeg_compress.dct_method = JDCT_FLOAT;
950         else
951                 result->jpeg_compress.dct_method = JDCT_IFAST;
952 //              result->jpeg_compress.dct_method = JDCT_ISLOW;
953
954 /* Fix sampling */
955         switch(mjpeg->fields)
956     {
957         case 1:
958                 mjpeg->jpeg_color_model = BC_YUV420P;
959                     result->jpeg_compress.comp_info[0].h_samp_factor = 2;
960                     result->jpeg_compress.comp_info[0].v_samp_factor = 2;
961                     result->jpeg_compress.comp_info[1].h_samp_factor = 1;
962                     result->jpeg_compress.comp_info[1].v_samp_factor = 1;
963                     result->jpeg_compress.comp_info[2].h_samp_factor = 1;
964                     result->jpeg_compress.comp_info[2].v_samp_factor = 1;
965                 break;
966         case 2:
967                 mjpeg->jpeg_color_model = BC_YUV422P;
968                     result->jpeg_compress.comp_info[0].h_samp_factor = 2;
969                     result->jpeg_compress.comp_info[0].v_samp_factor = 1;
970                     result->jpeg_compress.comp_info[1].h_samp_factor = 1;
971                     result->jpeg_compress.comp_info[1].v_samp_factor = 1;
972                     result->jpeg_compress.comp_info[2].h_samp_factor = 1;
973                     result->jpeg_compress.comp_info[2].v_samp_factor = 1;
974                 break;
975     }
976     allocate_temps(mjpeg);
977
978         result->mcu_rows[0] = new unsigned char *[16];
979         result->mcu_rows[1] = new unsigned char *[16];
980         result->mcu_rows[2] = new unsigned char *[16];
981
982         pthread_mutexattr_init(&mutex_attr);
983 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
984         pthread_mutex_init(&(result->input_lock), &mutex_attr);
985         pthread_mutex_lock(&(result->input_lock));
986         pthread_mutex_init(&(result->output_lock), &mutex_attr);
987         pthread_mutex_lock(&(result->output_lock));
988
989         pthread_attr_init(&attr);
990         pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_compress_loop, result);
991         return result;
992 }
993
994
995 void mjpeg_delete_compressor(mjpeg_compressor *engine)
996 {
997         engine->done = 1;
998         pthread_mutex_unlock(&(engine->input_lock));
999         pthread_join(engine->tid, 0);
1000         pthread_mutex_destroy(&(engine->input_lock));
1001         pthread_mutex_destroy(&(engine->output_lock));
1002         jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
1003         if(engine->output_buffer) delete [] engine->output_buffer;
1004         delete_rows(engine);
1005         delete [] engine->mcu_rows[0];
1006         delete [] engine->mcu_rows[1];
1007         delete [] engine->mcu_rows[2];
1008         delete engine;
1009 }
1010
1011 unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
1012 {
1013         return mjpeg->output_data;
1014 }
1015
1016 long mjpeg_output_field2(mjpeg_t *mjpeg)
1017 {
1018         return mjpeg->output_field2;
1019 }
1020
1021 long mjpeg_output_size(mjpeg_t *mjpeg)
1022 {
1023         return mjpeg->output_size;
1024 }
1025
1026 long mjpeg_output_allocated(mjpeg_t *mjpeg)
1027 {
1028         return mjpeg->output_allocated;
1029 }
1030
1031 void mjpeg_set_output_size(mjpeg_t *mjpeg, long output_size)
1032 {
1033         mjpeg->output_size = output_size;
1034 }
1035
1036
1037 int mjpeg_compress(mjpeg_t *mjpeg,
1038         unsigned char **row_pointers,
1039         unsigned char *y_plane,
1040         unsigned char *u_plane,
1041         unsigned char *v_plane,
1042         int color_model,
1043         int cpus)
1044 {
1045         int i, result = 0;
1046         int corrected_fields = mjpeg->fields;
1047         mjpeg->color_model = color_model;
1048         mjpeg->cpus = cpus;
1049
1050 //printf("mjpeg_compress 1 %d\n", color_model);
1051 /* Reset output buffer */
1052         reset_buffer(&mjpeg->output_data,
1053                 &mjpeg->output_size,
1054                 &mjpeg->output_allocated);
1055
1056 /* Create compression engines as needed */
1057         for(i = 0; i < mjpeg->fields; i++)
1058         {
1059                 if(!mjpeg->compressors[i])
1060                 {
1061                         mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
1062                 }
1063         }
1064
1065 /* Arm YUV buffers */
1066         mjpeg->row_argument = row_pointers;
1067         mjpeg->y_argument = y_plane;
1068         mjpeg->u_argument = u_plane;
1069         mjpeg->v_argument = v_plane;
1070 // User colormodel doesn't match encoder colormodel
1071 // Copy to interlacing buffer first
1072         if(mjpeg->color_model != mjpeg->jpeg_color_model ||
1073                 mjpeg->output_w != mjpeg->coded_w ||
1074                 mjpeg->output_h != mjpeg->coded_h)
1075         {
1076 /*
1077  * printf("mjpeg_compress %d %d %d %d\n",
1078  * mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_h);
1079  */
1080                 BC_CModels::transfer(0, row_pointers,
1081                         mjpeg->temp_rows[0][0], mjpeg->temp_rows[1][0], mjpeg->temp_rows[2][0],
1082                         y_plane, u_plane, v_plane,
1083                         0, 0, mjpeg->output_w, mjpeg->output_h,
1084                         0, 0, mjpeg->output_w, mjpeg->output_h,
1085                         mjpeg->color_model, mjpeg->jpeg_color_model, 0,
1086                         mjpeg->output_w, mjpeg->coded_w);
1087         }
1088
1089 /* Start the compressors on the image fields */
1090         if(mjpeg->deinterlace) corrected_fields = 1;
1091         for(i = 0; i < corrected_fields && !result; i++)
1092         {
1093                 unlock_compress_loop(mjpeg->compressors[i]);
1094
1095                 if(mjpeg->cpus < 2 && i < corrected_fields - 1)
1096                 {
1097                         lock_compress_loop(mjpeg->compressors[i]);
1098                 }
1099         }
1100
1101 /* Wait for the compressors and store in master output */
1102         for(i = 0; i < corrected_fields && !result; i++)
1103         {
1104                 if(mjpeg->cpus > 1 || i == corrected_fields - 1)
1105                 {
1106                         lock_compress_loop(mjpeg->compressors[i]);
1107                 }
1108
1109                 append_buffer(&mjpeg->output_data,
1110                         &mjpeg->output_size,
1111                         &mjpeg->output_allocated,
1112                         mjpeg->compressors[i]->output_buffer,
1113                         mjpeg->compressors[i]->output_size);
1114                 if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
1115         }
1116
1117         if(corrected_fields < mjpeg->fields)
1118         {
1119                 append_buffer(&mjpeg->output_data,
1120                         &mjpeg->output_size,
1121                         &mjpeg->output_allocated,
1122                         mjpeg->compressors[0]->output_buffer,
1123                         mjpeg->compressors[0]->output_size);
1124         }
1125 //printf("mjpeg_compress 2\n");
1126         return 0;
1127 }
1128
1129
1130
1131 int mjpeg_decompress(mjpeg_t *mjpeg,
1132         unsigned char *buffer,
1133         long buffer_len,
1134         long input_field2,
1135         unsigned char **row_pointers,
1136         unsigned char *y_plane,
1137         unsigned char *u_plane,
1138         unsigned char *v_plane,
1139         int color_model,
1140         int cpus)
1141 {
1142         int i, result = 0;
1143         int got_first_thread = 0;
1144
1145 //printf("mjpeg_decompress 1 %d\n", color_model);
1146         if(buffer_len == 0) return 1;
1147         if(input_field2 == 0 && mjpeg->fields > 1) return 1;
1148
1149 //printf("mjpeg_decompress 2\n");
1150 /* Create decompression engines as needed */
1151         for(i = 0; i < mjpeg->fields; i++)
1152         {
1153                 if(!mjpeg->decompressors[i])
1154                 {
1155                         mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
1156                 }
1157         }
1158
1159 //printf("mjpeg_decompress 3\n");
1160 /* Arm YUV buffers */
1161         mjpeg->row_argument = row_pointers;
1162         mjpeg->y_argument = y_plane;
1163         mjpeg->u_argument = u_plane;
1164         mjpeg->v_argument = v_plane;
1165         mjpeg->input_data = buffer;
1166         mjpeg->input_size = buffer_len;
1167         mjpeg->input_field2 = input_field2;
1168         mjpeg->color_model = color_model;
1169         mjpeg->cpus = cpus;
1170
1171 //printf("mjpeg_decompress 4 %02x %02x %d %02x %02x\n", buffer[0], buffer[1], input_field2, buffer[input_field2], buffer[input_field2 + 1]);
1172 /* Start decompressors */
1173         for(i = 0; i < mjpeg->fields && !result; i++)
1174         {
1175 //printf("mjpeg_decompress 5\n");
1176                 unlock_compress_loop(mjpeg->decompressors[i]);
1177 //printf("mjpeg_decompress 6\n");
1178
1179 // For dual CPUs, don't want second thread to start until temp data is allocated by the first.
1180 // For single CPUs, don't want two threads running simultaneously
1181                 if(mjpeg->cpus < 2 || !mjpeg->temp_data)
1182                 {
1183 //printf("mjpeg_decompress 7\n");
1184                         lock_compress_loop(mjpeg->decompressors[i]);
1185 //printf("mjpeg_decompress 8\n");
1186                         if(i == 0) got_first_thread = 1;
1187                 }
1188         }
1189
1190 //printf("mjpeg_decompress 10\n");
1191 /* Wait for decompressors */
1192         for(i = 0; i < mjpeg->fields && !result; i++)
1193         {
1194                 if(mjpeg->cpus > 1)
1195                 {
1196                         if(i > 0 || !got_first_thread)
1197                                 lock_compress_loop(mjpeg->decompressors[i]);
1198                 }
1199         }
1200
1201 /* Convert colormodel */
1202 // User colormodel didn't match decompressor
1203 /*
1204  *      if(!mjpeg->error &&
1205  *              (mjpeg->jpeg_color_model != mjpeg->color_model ||
1206  *              mjpeg->coded_w != mjpeg->output_w ||
1207  *              mjpeg->coded_h != mjpeg->output_h))
1208  */
1209
1210 //printf("mjpeg_decompress 6 %d %d %d %d\n", mjpeg->coded_w, mjpeg->coded_h, mjpeg->output_w, mjpeg->output_h);
1211         if((mjpeg->jpeg_color_model != mjpeg->color_model ||
1212                 mjpeg->coded_w != mjpeg->output_w ||
1213                 mjpeg->coded_h != mjpeg->output_h)
1214                 &&
1215                 (mjpeg->temp_data ||
1216                 !mjpeg->error))
1217         {
1218                 unsigned char *y_in = mjpeg->temp_rows[0][0];
1219                 unsigned char *u_in = mjpeg->temp_rows[1][0];
1220                 unsigned char *v_in = mjpeg->temp_rows[2][0];
1221
1222
1223 /*
1224  * printf("mjpeg_decompress 7 coded_w=%d coded_h=%d output_w=%d output_h=%d out_rowspan=%d in_colormodel=%d out_colormodel=%d\n",
1225  * mjpeg->coded_w,
1226  * mjpeg->coded_h,
1227  * mjpeg->output_w,
1228  * mjpeg->output_h,
1229  * mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w,
1230  * mjpeg->jpeg_color_model,
1231  * mjpeg->color_model);
1232  */
1233
1234                 BC_CModels::transfer(row_pointers, 0,
1235                         y_plane, u_plane, v_plane, y_in, u_in, v_in,
1236                         0, 0, mjpeg->output_w, mjpeg->output_h,
1237                         0, 0, mjpeg->output_w, mjpeg->output_h,
1238                         mjpeg->jpeg_color_model, mjpeg->color_model, 0,
1239                         mjpeg->coded_w, mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
1240 //printf("mjpeg_decompress 8\n");
1241         }
1242         return 0;
1243 }
1244
1245
1246 void mjpeg_set_deinterlace(mjpeg_t *mjpeg, int value)
1247 {
1248         mjpeg->deinterlace = value;
1249 }
1250
1251 void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
1252 {
1253         mjpeg->quality = quality;
1254 }
1255
1256 void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
1257 {
1258         mjpeg->use_float = use_float;
1259 }
1260
1261 void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
1262 {
1263         mjpeg->cpus = cpus;
1264 }
1265
1266 void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan)
1267 {
1268         mjpeg->rowspan = rowspan;
1269 }
1270
1271 int mjpeg_get_fields(mjpeg_t *mjpeg)
1272 {
1273         return mjpeg->fields;
1274 }
1275
1276
1277 mjpeg_t* mjpeg_new(int w,
1278         int h,
1279         int fields)
1280 {
1281         mjpeg_t *result = new mjpeg_t();
1282         memset(result, 0, sizeof(*result));
1283         pthread_mutexattr_t mutex_attr;
1284
1285         result->output_w = w;
1286         result->output_h = h;
1287         result->fields = fields;
1288         result->color_model = BC_RGB888;
1289         result->cpus = 1;
1290         result->quality = 80;
1291         result->use_float = 0;
1292
1293         pthread_mutexattr_init(&mutex_attr);
1294 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1295         pthread_mutex_init(&(result->decompress_init), &mutex_attr);
1296
1297
1298 // Calculate coded dimensions
1299 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1300
1301         result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
1302
1303         if(fields == 1)
1304                 result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
1305         else
1306                 result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
1307
1308
1309
1310 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1311         return result;
1312 }
1313
1314
1315
1316
1317 void mjpeg_delete(mjpeg_t *mjpeg)
1318 {
1319         int i;
1320 //printf("mjpeg_delete 1\n");
1321         for(i = 0; i < mjpeg->fields; i++)
1322         {
1323 //printf("mjpeg_delete 2\n");
1324                 if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
1325 //printf("mjpeg_delete 3\n");
1326                 if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
1327 //printf("mjpeg_delete 4\n");
1328         }
1329 //printf("mjpeg_delete 5\n");
1330         delete_temps(mjpeg);
1331 //printf("mjpeg_delete 6\n");
1332         delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
1333 //printf("mjpeg_delete 7\n");
1334         delete mjpeg;
1335 //printf("mjpeg_delete 2\n");
1336 }
1337
1338
1339 /* Open up a space to insert a marker */
1340 static void insert_space(unsigned char **buffer,
1341         long *buffer_size,
1342         long *buffer_allocated,
1343         long space_start,
1344         long space_len)
1345 {
1346         int in, out;
1347 // Make sure enough space is available
1348         if(*buffer_allocated - *buffer_size < space_len)
1349         {
1350                 *buffer_allocated += space_len;
1351                 unsigned char *new_buffer = new unsigned char[*buffer_allocated];
1352                 memcpy(new_buffer, *buffer, *buffer_size);
1353                 delete [] *buffer;
1354                 *buffer = new_buffer;
1355         }
1356
1357 // Shift data back
1358         for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
1359                 in >= space_start;
1360                 in--, out--)
1361         {
1362                 (*buffer)[out] = (*buffer)[in];
1363         }
1364         *buffer_size += space_len;
1365 }
1366
1367
1368 static inline int nextbyte(unsigned char *data, long *offset, long length)
1369 {
1370         if(length - *offset < 1) return 0;
1371         *offset += 1;
1372         return (unsigned char)data[*offset - 1];
1373 }
1374
1375 static inline int read_int32(unsigned char *data, long *offset, long length)
1376 {
1377         if(length - *offset < 4)
1378         {
1379                 *offset = length;
1380                 return 0;
1381         }
1382         *offset += 4;
1383         return ((((unsigned int)data[*offset - 4]) << 24) |
1384                 (((unsigned int)data[*offset - 3]) << 16) |
1385                 (((unsigned int)data[*offset - 2]) << 8) |
1386                 (((unsigned int)data[*offset - 1])));
1387 }
1388
1389 static inline int read_int16(unsigned char *data, long *offset, long length)
1390 {
1391         if(length - *offset < 2)
1392         {
1393                 *offset = length;
1394                 return 0;
1395         }
1396
1397         *offset += 2;
1398         return ((((unsigned int)data[*offset - 2]) << 8) |
1399                 (((unsigned int)data[*offset - 1])));
1400 }
1401
1402 static inline unsigned char read_char(unsigned char *data, long *offset, long length)
1403 {
1404         if(length - *offset < 1)
1405         {
1406                 *offset = length;
1407                 return 0;
1408         }
1409
1410         *offset += 1;
1411         return (unsigned char)data[*offset - 1];
1412 }
1413
1414 static inline int next_int16(unsigned char *data, long *offset, long length)
1415 {
1416         if(length - *offset < 2)
1417         {
1418                 return 0;
1419         }
1420
1421         return ((((unsigned int)data[*offset]) << 8) |
1422                 (((unsigned int)data[*offset + 1])));
1423 }
1424
1425 static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
1426 {
1427         if(length - *offset < 4)
1428         {
1429                 *offset = length;
1430                 return;
1431         }
1432
1433
1434         data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
1435         data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
1436         data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
1437         data[(*offset)++] = (unsigned char)(value & 0xff);
1438         return;
1439 }
1440
1441 static inline void write_char(unsigned char *data, long *offset, long length, unsigned char value)
1442 {
1443         if(length - *offset < 1)
1444         {
1445                 *offset = length;
1446                 return;
1447         }
1448
1449         data[(*offset)++] = value;
1450         return;
1451 }
1452
1453 static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
1454 {
1455         while(*offset < buffer_size - 1) {
1456                 if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff) {
1457                         (*offset) += 2;
1458                         return buffer[*offset - 1];
1459                 }
1460                 (*offset)++;
1461         }
1462         return 0;
1463 }
1464
1465 /* Find the next marker after offset and return 0 on success */
1466 static int find_marker(unsigned char *buffer,
1467         long *offset,
1468         long buffer_size,
1469         unsigned long marker_type)
1470 {
1471         long result = 0;
1472
1473         while(!result && *offset < buffer_size - 1)
1474         {
1475                 unsigned int marker = next_marker(buffer, offset, buffer_size);
1476                 if(marker == (marker_type & 0xff)) result = 1;
1477         }
1478
1479         return !result;
1480 }
1481
1482
1483 typedef struct
1484 {
1485         int field_size;
1486         int padded_field_size;
1487         int next_offset;
1488         int quant_offset;
1489         int huffman_offset;
1490         int image_offset;
1491         int scan_offset;
1492         int data_offset;
1493 } qt_hdr_t;
1494
1495 typedef struct
1496 {
1497         int field_number;
1498         int field_size;
1499         int unpadded_field_size;
1500 } avi_hdr_t;
1501
1502
1503 static int qt_table_offsets(unsigned char *buffer,
1504         long buffer_size,
1505         qt_hdr_t *header)
1506 {
1507         int done = 0;
1508         long offset = 0;
1509         int marker = 0;
1510         int field = 0;
1511         int len;
1512         int result = 0;
1513
1514         bzero(header, sizeof(qt_hdr_t) * 2);
1515
1516 // Read every marker to get the offsets for the headers
1517         for(field = 0; field < 2; field++)
1518         {
1519                 done = 0;
1520
1521                 while(!done)
1522                 {
1523                         marker = next_marker(buffer,
1524                                 &offset,
1525                                 buffer_size);
1526
1527                         len = 0;
1528
1529                         switch(marker)
1530                         {
1531                                 case M_SOI:
1532 // The first field may be padded
1533                                         if(field > 0)
1534                                         {
1535                                                 header[0].next_offset =
1536                                                         header[0].padded_field_size =
1537                                                         offset - 2;
1538                                         }
1539                                         len = 0;
1540                                         break;
1541
1542                                 case M_APP1:
1543 // Quicktime marker already exists.  Abort.
1544                                         if(buffer[offset + 6] == 'm' &&
1545                                                 buffer[offset + 7] == 'j' &&
1546                                                 buffer[offset + 8] == 'p' &&
1547                                                 buffer[offset + 9] == 'a')
1548                                         {
1549                                                 result = 1;
1550                                                 done = 1;
1551                                         }
1552                                         break;
1553
1554                                 case M_DQT:
1555                                         if(!header[field].quant_offset)
1556                                         {
1557                                                 header[field].quant_offset = offset - 2;
1558                                                 if(field > 0)
1559                                                         header[field].quant_offset -= header[0].next_offset;
1560                                         }
1561                                         len = read_int16(buffer, &offset, buffer_size);
1562                                         len -= 2;
1563                                         break;
1564
1565                                 case M_DHT:
1566                                         if(!header[field].huffman_offset)
1567                                         {
1568                                                 header[field].huffman_offset = offset - 2;
1569                                                 if(field > 0)
1570                                                         header[field].huffman_offset -= header[0].next_offset;
1571                                         }
1572                                         len = read_int16(buffer, &offset, buffer_size);
1573                                         len -= 2;
1574                                         break;
1575
1576                                 case M_SOF0:
1577                                         if(!header[field].image_offset)
1578                                         {
1579                                                 header[field].image_offset = offset - 2;
1580                                                 if(field > 0)
1581                                                         header[field].image_offset -= header[0].next_offset;
1582                                         }
1583                                         len = read_int16(buffer, &offset, buffer_size);
1584                                         len -= 2;
1585                                         break;
1586
1587                                 case M_SOS:
1588                                         header[field].scan_offset = offset - 2;
1589                                         if(field > 0)
1590                                                 header[field].scan_offset -= header[0].next_offset;
1591                                         len = read_int16(buffer, &offset, buffer_size);
1592                                         len -= 2;
1593                                         header[field].data_offset = offset + len;
1594                                         if(field > 0)
1595                                                 header[field].data_offset -= header[0].next_offset;
1596                                         break;
1597
1598 //                              case 0:
1599                                 case M_EOI:
1600                                         if(field > 0)
1601                                         {
1602                                                 header[field].field_size =
1603                                                         header[field].padded_field_size =
1604                                                         offset - header[0].next_offset;
1605                                                 header[field].next_offset = 0;
1606                                         }
1607                                         else
1608                                         {
1609 // Often misses second SOI but gets first EOI
1610 //                                              header[0].next_offset =
1611 //                                                      header[0].padded_field_size =
1612 //                                                      offset;
1613                                         }
1614 //printf("table_offsets M_EOI %d %x\n", field, offset);
1615                                         done = 1;
1616                                         len = 0;
1617                                         break;
1618
1619                                 default:
1620 // Junk appears between fields
1621                                         len = 0;
1622 //                                      len = read_int16(buffer, &offset, buffer_size);
1623 //                                      len -= 2;
1624                                         break;
1625                         }
1626
1627                         if(!done) offset += len;
1628                         if(offset >= buffer_size) done = 1;
1629                 }
1630 //printf("qt_table_offsets 10 %d\n", field);
1631         }
1632
1633         return result;
1634 }
1635
1636 static void insert_quicktime_marker(unsigned char *buffer,
1637         long buffer_size,
1638         long offset,
1639         qt_hdr_t *header)
1640 {
1641         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1642                         ((unsigned long)M_APP1 << 16) |
1643                         (QUICKTIME_MARKER_SIZE - 2));
1644         write_int32(buffer, &offset, buffer_size, 0);
1645         write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1646         write_int32(buffer, &offset, buffer_size, header->field_size);
1647         write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1648         write_int32(buffer, &offset, buffer_size, header->next_offset);
1649         write_int32(buffer, &offset, buffer_size, header->quant_offset);
1650         write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1651         write_int32(buffer, &offset, buffer_size, header->image_offset);
1652         write_int32(buffer, &offset, buffer_size, header->scan_offset);
1653         write_int32(buffer, &offset, buffer_size, header->data_offset);
1654 }
1655
1656
1657 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1658         long *buffer_size,
1659         long *buffer_allocated,
1660         int fields,
1661         long *field2_offset)
1662 {
1663         qt_hdr_t header[2];
1664         int exists = 0;
1665         *field2_offset = -1;
1666
1667         if(fields < 2) return;
1668
1669
1670 // Get offsets for tables in both fields
1671         exists = qt_table_offsets(*buffer, *buffer_size, header);
1672
1673 // APP1 for quicktime already exists
1674         if(exists) return;
1675
1676 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1677 //      header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1678 //if(*field2_offset == 0)
1679 //      fwrite(*buffer, *buffer_size, 1, stdout);
1680
1681
1682
1683         header[0].field_size += QUICKTIME_MARKER_SIZE;
1684         header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1685         header[0].next_offset += QUICKTIME_MARKER_SIZE;
1686         header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1687         header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1688         header[0].image_offset += QUICKTIME_MARKER_SIZE;
1689         header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1690         header[0].data_offset += QUICKTIME_MARKER_SIZE;
1691         header[1].field_size += QUICKTIME_MARKER_SIZE;
1692         header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1693         header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1694         header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1695         header[1].image_offset += QUICKTIME_MARKER_SIZE;
1696         header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1697         header[1].data_offset += QUICKTIME_MARKER_SIZE;
1698         *field2_offset = header[0].next_offset;
1699
1700
1701
1702 // Insert APP1 marker
1703         insert_space(buffer,
1704                 buffer_size,
1705                 buffer_allocated,
1706                 2,
1707                 QUICKTIME_MARKER_SIZE);
1708
1709         insert_quicktime_marker(*buffer,
1710                 *buffer_size,
1711                 2,
1712                 &header[0]);
1713
1714         insert_space(buffer,
1715                 buffer_size,
1716                 buffer_allocated,
1717                 header[0].next_offset + 2,
1718                 QUICKTIME_MARKER_SIZE);
1719
1720         header[1].next_offset = 0;
1721         insert_quicktime_marker(*buffer,
1722                 *buffer_size,
1723                 header[0].next_offset + 2,
1724                 &header[1]);
1725 }
1726
1727
1728 static int avi_table_offsets(unsigned char *buffer,
1729         long buffer_size,
1730         avi_hdr_t *header)
1731 {
1732         int field2 = mjpeg_get_field2(buffer, buffer_size);
1733
1734         header[0].field_number = 1;
1735         header[0].field_size = field2;
1736         header[0].unpadded_field_size = field2;
1737
1738         header[1].field_number = 2;
1739         header[1].field_size = buffer_size - field2;
1740         header[1].unpadded_field_size = buffer_size - field2;
1741         return 0;
1742 }
1743
1744 static void insert_avi_marker(unsigned char *buffer,
1745         long buffer_size,
1746         long offset,
1747         avi_hdr_t *header)
1748 {
1749         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1750                         ((unsigned long)M_APP0 << 16) |
1751                         (AVI_MARKER_SIZE - 2));
1752         write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1753
1754 // One version of McRoweSoft only allows field polarity while
1755 // another version allows field size.
1756         write_char(buffer, &offset, buffer_size, header->field_number);
1757         write_char(buffer, &offset, buffer_size, 0);
1758         write_int32(buffer, &offset, buffer_size, header->field_size);
1759         write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1760 }
1761
1762 void mjpeg_insert_avi_markers(unsigned char **buffer,
1763         long *buffer_size,
1764         long *buffer_allocated,
1765         int fields,
1766         long *field2_offset)
1767 {
1768         avi_hdr_t header[2];
1769         long offset = 0;
1770         *field2_offset = -1;
1771
1772
1773 // Test for existing marker
1774         if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1775         {
1776                 if((*buffer)[offset + 2] == 'A' &&
1777                         (*buffer)[offset + 3] == 'V' &&
1778                         (*buffer)[offset + 4] == 'I' &&
1779                         (*buffer)[offset + 5] == '1')
1780                         return;
1781         }
1782
1783
1784         avi_table_offsets(*buffer, *buffer_size, header);
1785
1786         header[0].field_size += AVI_MARKER_SIZE;
1787         header[0].unpadded_field_size += AVI_MARKER_SIZE;
1788         header[1].field_size += AVI_MARKER_SIZE;
1789         header[1].unpadded_field_size += AVI_MARKER_SIZE;
1790         *field2_offset = header[0].field_size;
1791
1792 // Insert APP0 marker into field 1
1793         insert_space(buffer,
1794                 buffer_size,
1795                 buffer_allocated,
1796                 2,
1797                 AVI_MARKER_SIZE);
1798         insert_avi_marker(*buffer,
1799                 *buffer_size,
1800                 2,
1801                 &header[0]);
1802
1803         insert_space(buffer,
1804                 buffer_size,
1805                 buffer_allocated,
1806                 *field2_offset + 2,
1807                 AVI_MARKER_SIZE);
1808         insert_avi_marker(*buffer,
1809                 *buffer_size,
1810                 *field2_offset + 2,
1811                 &header[1]);
1812
1813
1814
1815 }
1816
1817
1818 static void read_avi_markers(unsigned char *buffer,
1819         long buffer_size,
1820         avi_hdr_t *header)
1821 {
1822         long offset = 0;
1823         int marker_count = 0;
1824         int result = 0;
1825         int marker_size = 0;
1826         while(marker_count < 2 && offset < buffer_size && !result)
1827         {
1828                 result = find_marker(buffer,
1829                         &offset,
1830                         buffer_size,
1831                         M_APP0);
1832                 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1833
1834
1835                 if(!result && marker_size >= 16)
1836                 {
1837 // Marker size, AVI1
1838                         offset += 6;
1839 // field polarity
1840                         header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1841                         read_char(buffer, &offset, buffer_size);
1842                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1843                         header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1844                         marker_count++;
1845                 }
1846         }
1847 }
1848
1849
1850 static void read_quicktime_markers(unsigned char *buffer,
1851         long buffer_size,
1852         qt_hdr_t *header)
1853 {
1854         long offset = 0;
1855         int marker_count = 0;
1856         int result = 0;
1857
1858         while(marker_count < 2 && offset < buffer_size && !result)
1859         {
1860                 result = find_marker(buffer,
1861                         &offset,
1862                         buffer_size,
1863                         M_APP1);
1864
1865                 if(!result)
1866                 {
1867 // Marker size
1868                         read_int16(buffer, &offset, buffer_size);
1869 // Zero
1870                         read_int32(buffer, &offset, buffer_size);
1871 // MJPA
1872                         read_int32(buffer, &offset, buffer_size);
1873 // Information
1874                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1875                         header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1876                         header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1877                         header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1878                         header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1879                         header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1880                         header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1881                         header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1882                         marker_count++;
1883                 }
1884         }
1885 //printf("read_quicktime_markers 1 %d\n", marker_count);
1886 }
1887
1888 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1889 {
1890         qt_hdr_t header[2];
1891         bzero(&header, sizeof(qt_hdr_t) * 2);
1892
1893         read_quicktime_markers(buffer, buffer_size, header);
1894         return header[0].next_offset;
1895 }
1896
1897 long mjpeg_get_avi_field2(unsigned char *buffer,
1898         long buffer_size,
1899         int *field_dominance)
1900 {
1901         avi_hdr_t header[2];
1902         bzero(&header, sizeof(avi_hdr_t) * 2);
1903         read_avi_markers(buffer, buffer_size, header);
1904
1905         *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1906
1907 // One version of McRoweSoft only allows field polarity while
1908 // another version allows field size.
1909         if(header[0].field_size)
1910         {
1911                 return header[0].field_size;
1912         }
1913         else
1914         {
1915                 return mjpeg_get_field2(buffer, buffer_size);
1916         }
1917         return 0;
1918 }
1919
1920 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1921 {
1922         int total_fields = 0;
1923         long field2_offset = 0;
1924         int i;
1925
1926         for(i = 0; i < buffer_size; i++)
1927         {
1928                 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1929                 {
1930                         total_fields++;
1931                         field2_offset = i;
1932                         if(total_fields == 2) break;
1933                 }
1934         }
1935         return field2_offset;
1936 }
1937
1938 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1939 {
1940           long offset = 0;
1941           find_marker(data,
1942                           &offset,
1943                           data_size,
1944                           M_SOF0);
1945           *h = (data[offset + 3] << 8) | (data[offset + 4]);
1946           *w = (data[offset + 5] << 8) | (data[offset + 6]);
1947 }
1948
1949