asset drag/drop to viewers, bluebanana bug, listbox fontlist highlight
[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
1531 static int qt_table_offsets(unsigned char *buffer,
1532         long buffer_size,
1533         qt_hdr_t *header)
1534 {
1535         int done = 0;
1536         long offset = 0;
1537         int marker = 0;
1538         int field = 0;
1539         int len;
1540         int result = 0;
1541
1542         bzero(header, sizeof(qt_hdr_t) * 2);
1543
1544 // Read every marker to get the offsets for the headers
1545         for(field = 0; field < 2; field++)
1546         {
1547                 done = 0;
1548
1549                 while(!done)
1550                 {
1551                         marker = next_marker(buffer,
1552                                 &offset,
1553                                 buffer_size);
1554
1555                         len = 0;
1556
1557                         switch(marker)
1558                         {
1559                                 case M_SOI:
1560 // The first field may be padded
1561                                         if(field > 0)
1562                                         {
1563                                                 header[0].next_offset =
1564                                                         header[0].padded_field_size =
1565                                                         offset - 2;
1566                                         }
1567                                         len = 0;
1568                                         break;
1569
1570                                 case M_APP1:
1571 // Quicktime marker already exists.  Abort.
1572                                         if(buffer[offset + 6] == 'm' &&
1573                                                 buffer[offset + 7] == 'j' &&
1574                                                 buffer[offset + 8] == 'p' &&
1575                                                 buffer[offset + 9] == 'a')
1576                                         {
1577                                                 result = 1;
1578                                                 done = 1;
1579                                         }
1580                                         break;
1581
1582                                 case M_DQT:
1583                                         if(!header[field].quant_offset)
1584                                         {
1585                                                 header[field].quant_offset = offset - 2;
1586                                                 if(field > 0)
1587                                                         header[field].quant_offset -= header[0].next_offset;
1588                                         }
1589                                         len = read_int16(buffer, &offset, buffer_size);
1590                                         len -= 2;
1591                                         break;
1592
1593                                 case M_DHT:
1594                                         if(!header[field].huffman_offset)
1595                                         {
1596                                                 header[field].huffman_offset = offset - 2;
1597                                                 if(field > 0)
1598                                                         header[field].huffman_offset -= header[0].next_offset;
1599                                         }
1600                                         len = read_int16(buffer, &offset, buffer_size);
1601                                         len -= 2;
1602                                         break;
1603
1604                                 case M_SOF0:
1605                                         if(!header[field].image_offset)
1606                                         {
1607                                                 header[field].image_offset = offset - 2;
1608                                                 if(field > 0)
1609                                                         header[field].image_offset -= header[0].next_offset;
1610                                         }
1611                                         len = read_int16(buffer, &offset, buffer_size);
1612                                         len -= 2;
1613                                         break;
1614
1615                                 case M_SOS:
1616                                         header[field].scan_offset = offset - 2;
1617                                         if(field > 0)
1618                                                 header[field].scan_offset -= header[0].next_offset;
1619                                         len = read_int16(buffer, &offset, buffer_size);
1620                                         len -= 2;
1621                                         header[field].data_offset = offset + len;
1622                                         if(field > 0)
1623                                                 header[field].data_offset -= header[0].next_offset;
1624                                         break;
1625
1626 //                              case 0:
1627                                 case M_EOI:
1628                                         if(field > 0)
1629                                         {
1630                                                 header[field].field_size =
1631                                                         header[field].padded_field_size =
1632                                                         offset - header[0].next_offset;
1633                                                 header[field].next_offset = 0;
1634                                         }
1635                                         else
1636                                         {
1637 // Often misses second SOI but gets first EOI
1638 //                                              header[0].next_offset =
1639 //                                                      header[0].padded_field_size =
1640 //                                                      offset;
1641                                         }
1642 //printf("table_offsets M_EOI %d %x\n", field, offset);
1643                                         done = 1;
1644                                         len = 0;
1645                                         break;
1646
1647                                 default:
1648 // Junk appears between fields
1649                                         len = 0;
1650 //                                      len = read_int16(buffer, &offset, buffer_size);
1651 //                                      len -= 2;
1652                                         break;
1653                         }
1654
1655                         if(!done) offset += len;
1656                         if(offset >= buffer_size) done = 1;
1657                 }
1658 //printf("qt_table_offsets 10 %d\n", field);
1659         }
1660
1661         return result;
1662 }
1663
1664 static void insert_quicktime_marker(unsigned char *buffer,
1665         long buffer_size,
1666         long offset,
1667         qt_hdr_t *header)
1668 {
1669         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1670                         ((unsigned long)M_APP1 << 16) |
1671                         (QUICKTIME_MARKER_SIZE - 2));
1672         write_int32(buffer, &offset, buffer_size, 0);
1673         write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1674         write_int32(buffer, &offset, buffer_size, header->field_size);
1675         write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1676         write_int32(buffer, &offset, buffer_size, header->next_offset);
1677         write_int32(buffer, &offset, buffer_size, header->quant_offset);
1678         write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1679         write_int32(buffer, &offset, buffer_size, header->image_offset);
1680         write_int32(buffer, &offset, buffer_size, header->scan_offset);
1681         write_int32(buffer, &offset, buffer_size, header->data_offset);
1682 }
1683
1684
1685 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1686         long *buffer_size,
1687         long *buffer_allocated,
1688         int fields,
1689         long *field2_offset)
1690 {
1691         qt_hdr_t header[2];
1692         int exists = 0;
1693         *field2_offset = -1;
1694
1695         if(fields < 2) return;
1696
1697
1698 // Get offsets for tables in both fields
1699         exists = qt_table_offsets(*buffer, *buffer_size, header);
1700
1701 // APP1 for quicktime already exists
1702         if(exists) return;
1703
1704 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1705 //      header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1706 //if(*field2_offset == 0)
1707 //      fwrite(*buffer, *buffer_size, 1, stdout);
1708
1709
1710
1711         header[0].field_size += QUICKTIME_MARKER_SIZE;
1712         header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1713         header[0].next_offset += QUICKTIME_MARKER_SIZE;
1714         header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1715         header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1716         header[0].image_offset += QUICKTIME_MARKER_SIZE;
1717         header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1718         header[0].data_offset += QUICKTIME_MARKER_SIZE;
1719         header[1].field_size += QUICKTIME_MARKER_SIZE;
1720         header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1721         header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1722         header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1723         header[1].image_offset += QUICKTIME_MARKER_SIZE;
1724         header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1725         header[1].data_offset += QUICKTIME_MARKER_SIZE;
1726         *field2_offset = header[0].next_offset;
1727
1728
1729
1730 // Insert APP1 marker
1731         insert_space(buffer,
1732                 buffer_size,
1733                 buffer_allocated,
1734                 2,
1735                 QUICKTIME_MARKER_SIZE);
1736
1737         insert_quicktime_marker(*buffer,
1738                 *buffer_size,
1739                 2,
1740                 &header[0]);
1741
1742         insert_space(buffer,
1743                 buffer_size,
1744                 buffer_allocated,
1745                 header[0].next_offset + 2,
1746                 QUICKTIME_MARKER_SIZE);
1747
1748         header[1].next_offset = 0;
1749         insert_quicktime_marker(*buffer,
1750                 *buffer_size,
1751                 header[0].next_offset + 2,
1752                 &header[1]);
1753 }
1754
1755
1756 static int avi_table_offsets(unsigned char *buffer,
1757         long buffer_size,
1758         avi_hdr_t *header)
1759 {
1760         int field2 = mjpeg_get_field2(buffer, buffer_size);
1761
1762         header[0].field_number = 1;
1763         header[0].field_size = field2;
1764         header[0].unpadded_field_size = field2;
1765
1766         header[1].field_number = 2;
1767         header[1].field_size = buffer_size - field2;
1768         header[1].unpadded_field_size = buffer_size - field2;
1769         return 0;
1770 }
1771
1772 static void insert_avi_marker(unsigned char *buffer,
1773         long buffer_size,
1774         long offset,
1775         avi_hdr_t *header)
1776 {
1777         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1778                         ((unsigned long)M_APP0 << 16) |
1779                         (AVI_MARKER_SIZE - 2));
1780         write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1781
1782 // One version of McRoweSoft only allows field polarity while
1783 // another version allows field size.
1784         write_char(buffer, &offset, buffer_size, header->field_number);
1785         write_char(buffer, &offset, buffer_size, 0);
1786         write_int32(buffer, &offset, buffer_size, header->field_size);
1787         write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1788 }
1789
1790 void mjpeg_insert_avi_markers(unsigned char **buffer,
1791         long *buffer_size,
1792         long *buffer_allocated,
1793         int fields,
1794         long *field2_offset)
1795 {
1796         avi_hdr_t header[2];
1797         long offset = 0;
1798         *field2_offset = -1;
1799
1800
1801 // Test for existing marker
1802         if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1803         {
1804                 if((*buffer)[offset + 2] == 'A' &&
1805                         (*buffer)[offset + 3] == 'V' &&
1806                         (*buffer)[offset + 4] == 'I' &&
1807                         (*buffer)[offset + 5] == '1')
1808                         return;
1809         }
1810
1811
1812         avi_table_offsets(*buffer, *buffer_size, header);
1813
1814         header[0].field_size += AVI_MARKER_SIZE;
1815         header[0].unpadded_field_size += AVI_MARKER_SIZE;
1816         header[1].field_size += AVI_MARKER_SIZE;
1817         header[1].unpadded_field_size += AVI_MARKER_SIZE;
1818         *field2_offset = header[0].field_size;
1819
1820 // Insert APP0 marker into field 1
1821         insert_space(buffer,
1822                 buffer_size,
1823                 buffer_allocated,
1824                 2,
1825                 AVI_MARKER_SIZE);
1826         insert_avi_marker(*buffer,
1827                 *buffer_size,
1828                 2,
1829                 &header[0]);
1830
1831         insert_space(buffer,
1832                 buffer_size,
1833                 buffer_allocated,
1834                 *field2_offset + 2,
1835                 AVI_MARKER_SIZE);
1836         insert_avi_marker(*buffer,
1837                 *buffer_size,
1838                 *field2_offset + 2,
1839                 &header[1]);
1840
1841
1842
1843 }
1844
1845
1846 static void read_avi_markers(unsigned char *buffer,
1847         long buffer_size,
1848         avi_hdr_t *header)
1849 {
1850         long offset = 0;
1851         int marker_count = 0;
1852         int result = 0;
1853         int marker_size = 0;
1854         while(marker_count < 2 && offset < buffer_size && !result)
1855         {
1856                 result = find_marker(buffer,
1857                         &offset,
1858                         buffer_size,
1859                         M_APP0);
1860                 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1861
1862
1863                 if(!result && marker_size >= 16)
1864                 {
1865 // Marker size, AVI1
1866                         offset += 6;
1867 // field polarity
1868                         header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1869                         read_char(buffer, &offset, buffer_size);
1870                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1871                         header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1872                         marker_count++;
1873                 }
1874         }
1875 }
1876
1877
1878 static void read_quicktime_markers(unsigned char *buffer,
1879         long buffer_size,
1880         qt_hdr_t *header)
1881 {
1882         long offset = 0;
1883         int marker_count = 0;
1884         int result = 0;
1885
1886         while(marker_count < 2 && offset < buffer_size && !result)
1887         {
1888                 result = find_marker(buffer,
1889                         &offset,
1890                         buffer_size,
1891                         M_APP1);
1892
1893                 if(!result)
1894                 {
1895 // Marker size
1896                         read_int16(buffer, &offset, buffer_size);
1897 // Zero
1898                         read_int32(buffer, &offset, buffer_size);
1899 // MJPA
1900                         read_int32(buffer, &offset, buffer_size);
1901 // Information
1902                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1903                         header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1904                         header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1905                         header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1906                         header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1907                         header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1908                         header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1909                         header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1910                         marker_count++;
1911                 }
1912         }
1913 //printf("read_quicktime_markers 1 %d\n", marker_count);
1914 }
1915
1916 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1917 {
1918         qt_hdr_t header[2];
1919         bzero(&header, sizeof(qt_hdr_t) * 2);
1920
1921         read_quicktime_markers(buffer, buffer_size, header);
1922         return header[0].next_offset;
1923 }
1924
1925 long mjpeg_get_avi_field2(unsigned char *buffer,
1926         long buffer_size,
1927         int *field_dominance)
1928 {
1929         avi_hdr_t header[2];
1930         bzero(&header, sizeof(avi_hdr_t) * 2);
1931         read_avi_markers(buffer, buffer_size, header);
1932
1933         *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1934
1935 // One version of McRoweSoft only allows field polarity while
1936 // another version allows field size.
1937         if(header[0].field_size)
1938         {
1939                 return header[0].field_size;
1940         }
1941         else
1942         {
1943                 return mjpeg_get_field2(buffer, buffer_size);
1944         }
1945         return 0;
1946 }
1947
1948 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1949 {
1950         int total_fields = 0;
1951         long field2_offset = 0;
1952         int i;
1953
1954         for(i = 0; i < buffer_size; i++)
1955         {
1956                 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1957                 {
1958                         total_fields++;
1959                         field2_offset = i;
1960                         if(total_fields == 2) break;
1961                 }
1962         }
1963         return field2_offset;
1964 }
1965
1966 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1967 {
1968           long offset = 0;
1969           find_marker(data,
1970                           &offset,
1971                           data_size,
1972                           M_SOF0);
1973           *h = (data[offset + 3] << 8) | (data[offset + 4]);
1974           *w = (data[offset + 5] << 8) | (data[offset + 6]);
1975 }
1976
1977