prevent popup deactivation while button_down
[goodguy/history.git] / cinelerra-5.0 / 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
778         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,
1081                         row_pointers,
1082                         mjpeg->temp_rows[0][0],
1083                         mjpeg->temp_rows[1][0],
1084                         mjpeg->temp_rows[2][0],
1085                         y_plane,
1086                         u_plane,
1087                         v_plane,
1088                         0,
1089                         0,
1090                         mjpeg->output_w,
1091                         mjpeg->output_h,
1092                         0,
1093                         0,
1094                         mjpeg->output_w,
1095                         mjpeg->output_h,
1096                         mjpeg->color_model,
1097                         mjpeg->jpeg_color_model,
1098                         0,
1099                         mjpeg->output_w,
1100                         mjpeg->coded_w);
1101         }
1102
1103 /* Start the compressors on the image fields */
1104         if(mjpeg->deinterlace) corrected_fields = 1;
1105         for(i = 0; i < corrected_fields && !result; i++)
1106         {
1107                 unlock_compress_loop(mjpeg->compressors[i]);
1108
1109                 if(mjpeg->cpus < 2 && i < corrected_fields - 1)
1110                 {
1111                         lock_compress_loop(mjpeg->compressors[i]);
1112                 }
1113         }
1114
1115 /* Wait for the compressors and store in master output */
1116         for(i = 0; i < corrected_fields && !result; i++)
1117         {
1118                 if(mjpeg->cpus > 1 || i == corrected_fields - 1)
1119                 {
1120                         lock_compress_loop(mjpeg->compressors[i]);
1121                 }
1122
1123                 append_buffer(&mjpeg->output_data,
1124                         &mjpeg->output_size,
1125                         &mjpeg->output_allocated,
1126                         mjpeg->compressors[i]->output_buffer,
1127                         mjpeg->compressors[i]->output_size);
1128                 if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
1129         }
1130
1131         if(corrected_fields < mjpeg->fields)
1132         {
1133                 append_buffer(&mjpeg->output_data,
1134                         &mjpeg->output_size,
1135                         &mjpeg->output_allocated,
1136                         mjpeg->compressors[0]->output_buffer,
1137                         mjpeg->compressors[0]->output_size);
1138         }
1139 //printf("mjpeg_compress 2\n");
1140         return 0;
1141 }
1142
1143
1144
1145 int mjpeg_decompress(mjpeg_t *mjpeg,
1146         unsigned char *buffer,
1147         long buffer_len,
1148         long input_field2,
1149         unsigned char **row_pointers,
1150         unsigned char *y_plane,
1151         unsigned char *u_plane,
1152         unsigned char *v_plane,
1153         int color_model,
1154         int cpus)
1155 {
1156         int i, result = 0;
1157         int got_first_thread = 0;
1158
1159 //printf("mjpeg_decompress 1 %d\n", color_model);
1160         if(buffer_len == 0) return 1;
1161         if(input_field2 == 0 && mjpeg->fields > 1) return 1;
1162
1163 //printf("mjpeg_decompress 2\n");
1164 /* Create decompression engines as needed */
1165         for(i = 0; i < mjpeg->fields; i++)
1166         {
1167                 if(!mjpeg->decompressors[i])
1168                 {
1169                         mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
1170                 }
1171         }
1172
1173 //printf("mjpeg_decompress 3\n");
1174 /* Arm YUV buffers */
1175         mjpeg->row_argument = row_pointers;
1176         mjpeg->y_argument = y_plane;
1177         mjpeg->u_argument = u_plane;
1178         mjpeg->v_argument = v_plane;
1179         mjpeg->input_data = buffer;
1180         mjpeg->input_size = buffer_len;
1181         mjpeg->input_field2 = input_field2;
1182         mjpeg->color_model = color_model;
1183         mjpeg->cpus = cpus;
1184
1185 //printf("mjpeg_decompress 4 %02x %02x %d %02x %02x\n", buffer[0], buffer[1], input_field2, buffer[input_field2], buffer[input_field2 + 1]);
1186 /* Start decompressors */
1187         for(i = 0; i < mjpeg->fields && !result; i++)
1188         {
1189 //printf("mjpeg_decompress 5\n");
1190                 unlock_compress_loop(mjpeg->decompressors[i]);
1191 //printf("mjpeg_decompress 6\n");
1192
1193 // For dual CPUs, don't want second thread to start until temp data is allocated by the first.
1194 // For single CPUs, don't want two threads running simultaneously
1195                 if(mjpeg->cpus < 2 || !mjpeg->temp_data)
1196                 {
1197 //printf("mjpeg_decompress 7\n");
1198                         lock_compress_loop(mjpeg->decompressors[i]);
1199 //printf("mjpeg_decompress 8\n");
1200                         if(i == 0) got_first_thread = 1;
1201                 }
1202         }
1203
1204 //printf("mjpeg_decompress 10\n");
1205 /* Wait for decompressors */
1206         for(i = 0; i < mjpeg->fields && !result; i++)
1207         {
1208                 if(mjpeg->cpus > 1)
1209                 {
1210                         if(i > 0 || !got_first_thread)
1211                                 lock_compress_loop(mjpeg->decompressors[i]);
1212                 }
1213         }
1214
1215 /* Convert colormodel */
1216 // User colormodel didn't match decompressor
1217 /*
1218  *      if(!mjpeg->error &&
1219  *              (mjpeg->jpeg_color_model != mjpeg->color_model ||
1220  *              mjpeg->coded_w != mjpeg->output_w ||
1221  *              mjpeg->coded_h != mjpeg->output_h))
1222  */
1223
1224 //printf("mjpeg_decompress 6 %d %d %d %d\n", mjpeg->coded_w, mjpeg->coded_h, mjpeg->output_w, mjpeg->output_h);
1225         if((mjpeg->jpeg_color_model != mjpeg->color_model ||
1226                 mjpeg->coded_w != mjpeg->output_w ||
1227                 mjpeg->coded_h != mjpeg->output_h)
1228                 &&
1229                 (mjpeg->temp_data ||
1230                 !mjpeg->error))
1231         {
1232                 unsigned char *y_in = mjpeg->temp_rows[0][0];
1233                 unsigned char *u_in = mjpeg->temp_rows[1][0];
1234                 unsigned char *v_in = mjpeg->temp_rows[2][0];
1235
1236
1237 /*
1238  * 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",
1239  * mjpeg->coded_w,
1240  * mjpeg->coded_h,
1241  * mjpeg->output_w,
1242  * mjpeg->output_h,
1243  * mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w,
1244  * mjpeg->jpeg_color_model,
1245  * mjpeg->color_model);
1246  */
1247
1248                 BC_CModels::transfer(row_pointers,
1249                         0,
1250                         y_plane,
1251                         u_plane,
1252                         v_plane,
1253                         y_in,
1254                         u_in,
1255                         v_in,
1256                         0,
1257                         0,
1258                         mjpeg->output_w,
1259                         mjpeg->output_h,
1260                         0,
1261                         0,
1262                         mjpeg->output_w,
1263                         mjpeg->output_h,
1264                         mjpeg->jpeg_color_model,
1265                         mjpeg->color_model,
1266                         0,
1267                         mjpeg->coded_w,
1268                         mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
1269 //printf("mjpeg_decompress 8\n");
1270         }
1271         return 0;
1272 }
1273
1274
1275 void mjpeg_set_deinterlace(mjpeg_t *mjpeg, int value)
1276 {
1277         mjpeg->deinterlace = value;
1278 }
1279
1280 void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
1281 {
1282         mjpeg->quality = quality;
1283 }
1284
1285 void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
1286 {
1287         mjpeg->use_float = use_float;
1288 }
1289
1290 void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
1291 {
1292         mjpeg->cpus = cpus;
1293 }
1294
1295 void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan)
1296 {
1297         mjpeg->rowspan = rowspan;
1298 }
1299
1300 int mjpeg_get_fields(mjpeg_t *mjpeg)
1301 {
1302         return mjpeg->fields;
1303 }
1304
1305
1306 mjpeg_t* mjpeg_new(int w,
1307         int h,
1308         int fields)
1309 {
1310         mjpeg_t *result = new mjpeg_t();
1311         memset(result, 0, sizeof(*result));
1312         pthread_mutexattr_t mutex_attr;
1313
1314         result->output_w = w;
1315         result->output_h = h;
1316         result->fields = fields;
1317         result->color_model = BC_RGB888;
1318         result->cpus = 1;
1319         result->quality = 80;
1320         result->use_float = 0;
1321
1322         pthread_mutexattr_init(&mutex_attr);
1323 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1324         pthread_mutex_init(&(result->decompress_init), &mutex_attr);
1325
1326
1327 // Calculate coded dimensions
1328 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1329
1330         result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
1331
1332         if(fields == 1)
1333                 result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
1334         else
1335                 result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
1336
1337
1338
1339 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1340         return result;
1341 }
1342
1343
1344
1345
1346 void mjpeg_delete(mjpeg_t *mjpeg)
1347 {
1348         int i;
1349 //printf("mjpeg_delete 1\n");
1350         for(i = 0; i < mjpeg->fields; i++)
1351         {
1352 //printf("mjpeg_delete 2\n");
1353                 if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
1354 //printf("mjpeg_delete 3\n");
1355                 if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
1356 //printf("mjpeg_delete 4\n");
1357         }
1358 //printf("mjpeg_delete 5\n");
1359         delete_temps(mjpeg);
1360 //printf("mjpeg_delete 6\n");
1361         delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
1362 //printf("mjpeg_delete 7\n");
1363         delete mjpeg;
1364 //printf("mjpeg_delete 2\n");
1365 }
1366
1367
1368 /* Open up a space to insert a marker */
1369 static void insert_space(unsigned char **buffer,
1370         long *buffer_size,
1371         long *buffer_allocated,
1372         long space_start,
1373         long space_len)
1374 {
1375         int in, out;
1376 // Make sure enough space is available
1377         if(*buffer_allocated - *buffer_size < space_len)
1378         {
1379                 *buffer_allocated += space_len;
1380                 unsigned char *new_buffer = new unsigned char[*buffer_allocated];
1381                 memcpy(new_buffer, *buffer, *buffer_size);
1382                 delete [] *buffer;
1383                 *buffer = new_buffer;
1384         }
1385
1386 // Shift data back
1387         for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
1388                 in >= space_start;
1389                 in--, out--)
1390         {
1391                 (*buffer)[out] = (*buffer)[in];
1392         }
1393         *buffer_size += space_len;
1394 }
1395
1396
1397 static inline int nextbyte(unsigned char *data, long *offset, long length)
1398 {
1399         if(length - *offset < 1) return 0;
1400         *offset += 1;
1401         return (unsigned char)data[*offset - 1];
1402 }
1403
1404 static inline int read_int32(unsigned char *data, long *offset, long length)
1405 {
1406         if(length - *offset < 4)
1407         {
1408                 *offset = length;
1409                 return 0;
1410         }
1411         *offset += 4;
1412         return ((((unsigned int)data[*offset - 4]) << 24) |
1413                 (((unsigned int)data[*offset - 3]) << 16) |
1414                 (((unsigned int)data[*offset - 2]) << 8) |
1415                 (((unsigned int)data[*offset - 1])));
1416 }
1417
1418 static inline int read_int16(unsigned char *data, long *offset, long length)
1419 {
1420         if(length - *offset < 2)
1421         {
1422                 *offset = length;
1423                 return 0;
1424         }
1425
1426         *offset += 2;
1427         return ((((unsigned int)data[*offset - 2]) << 8) |
1428                 (((unsigned int)data[*offset - 1])));
1429 }
1430
1431 static inline unsigned char read_char(unsigned char *data, long *offset, long length)
1432 {
1433         if(length - *offset < 1)
1434         {
1435                 *offset = length;
1436                 return 0;
1437         }
1438
1439         *offset += 1;
1440         return (unsigned char)data[*offset - 1];
1441 }
1442
1443 static inline int next_int16(unsigned char *data, long *offset, long length)
1444 {
1445         if(length - *offset < 2)
1446         {
1447                 return 0;
1448         }
1449
1450         return ((((unsigned int)data[*offset]) << 8) |
1451                 (((unsigned int)data[*offset + 1])));
1452 }
1453
1454 static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
1455 {
1456         if(length - *offset < 4)
1457         {
1458                 *offset = length;
1459                 return;
1460         }
1461
1462
1463         data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
1464         data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
1465         data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
1466         data[(*offset)++] = (unsigned char)(value & 0xff);
1467         return;
1468 }
1469
1470 static inline void write_char(unsigned char *data, long *offset, long length, unsigned char value)
1471 {
1472         if(length - *offset < 1)
1473         {
1474                 *offset = length;
1475                 return;
1476         }
1477
1478         data[(*offset)++] = value;
1479         return;
1480 }
1481
1482 static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
1483 {
1484         while(*offset < buffer_size - 1) {
1485                 if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff) {
1486                         (*offset) += 2;
1487                         return buffer[*offset - 1];
1488                 }
1489                 (*offset)++;
1490         }
1491         return 0;
1492 }
1493
1494 /* Find the next marker after offset and return 0 on success */
1495 static int find_marker(unsigned char *buffer,
1496         long *offset,
1497         long buffer_size,
1498         unsigned long marker_type)
1499 {
1500         long result = 0;
1501
1502         while(!result && *offset < buffer_size - 1)
1503         {
1504                 unsigned int marker = next_marker(buffer, offset, buffer_size);
1505                 if(marker == (marker_type & 0xff)) result = 1;
1506         }
1507
1508         return !result;
1509 }
1510
1511
1512 typedef struct
1513 {
1514         int field_size;
1515         int padded_field_size;
1516         int next_offset;
1517         int quant_offset;
1518         int huffman_offset;
1519         int image_offset;
1520         int scan_offset;
1521         int data_offset;
1522 } qt_hdr_t;
1523
1524 typedef struct
1525 {
1526         int field_number;
1527         int field_size;
1528         int unpadded_field_size;
1529 } avi_hdr_t;
1530
1531 #define LML_MARKER_SIZE 0x2c
1532 #define LML_MARKER_TAG 0xffe3
1533 void insert_lml33_markers(unsigned char **buffer,
1534         long *field2_offset,
1535         long *buffer_size,
1536         long *buffer_allocated)
1537 {
1538         long marker_offset = -1;
1539
1540 /* Search for existing marker to replace */
1541 //      marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);
1542
1543 /* Insert new marker */
1544         if(marker_offset < 0)
1545         {
1546                 marker_offset = 2;
1547                 insert_space(buffer,
1548                         buffer_size,
1549                         buffer_allocated,
1550                         2,
1551                         LML_MARKER_SIZE);
1552         }
1553 }
1554
1555 static int qt_table_offsets(unsigned char *buffer,
1556         long buffer_size,
1557         qt_hdr_t *header)
1558 {
1559         int done = 0;
1560         long offset = 0;
1561         int marker = 0;
1562         int field = 0;
1563         int len;
1564         int result = 0;
1565
1566         bzero(header, sizeof(qt_hdr_t) * 2);
1567
1568 // Read every marker to get the offsets for the headers
1569         for(field = 0; field < 2; field++)
1570         {
1571                 done = 0;
1572
1573                 while(!done)
1574                 {
1575                         marker = next_marker(buffer,
1576                                 &offset,
1577                                 buffer_size);
1578
1579                         len = 0;
1580
1581                         switch(marker)
1582                         {
1583                                 case M_SOI:
1584 // The first field may be padded
1585                                         if(field > 0)
1586                                         {
1587                                                 header[0].next_offset =
1588                                                         header[0].padded_field_size =
1589                                                         offset - 2;
1590                                         }
1591                                         len = 0;
1592                                         break;
1593
1594                                 case M_APP1:
1595 // Quicktime marker already exists.  Abort.
1596                                         if(buffer[offset + 6] == 'm' &&
1597                                                 buffer[offset + 7] == 'j' &&
1598                                                 buffer[offset + 8] == 'p' &&
1599                                                 buffer[offset + 9] == 'a')
1600                                         {
1601                                                 result = 1;
1602                                                 done = 1;
1603                                         }
1604                                         break;
1605
1606                                 case M_DQT:
1607                                         if(!header[field].quant_offset)
1608                                         {
1609                                                 header[field].quant_offset = offset - 2;
1610                                                 if(field > 0)
1611                                                         header[field].quant_offset -= header[0].next_offset;
1612                                         }
1613                                         len = read_int16(buffer, &offset, buffer_size);
1614                                         len -= 2;
1615                                         break;
1616
1617                                 case M_DHT:
1618                                         if(!header[field].huffman_offset)
1619                                         {
1620                                                 header[field].huffman_offset = offset - 2;
1621                                                 if(field > 0)
1622                                                         header[field].huffman_offset -= header[0].next_offset;
1623                                         }
1624                                         len = read_int16(buffer, &offset, buffer_size);
1625                                         len -= 2;
1626                                         break;
1627
1628                                 case M_SOF0:
1629                                         if(!header[field].image_offset)
1630                                         {
1631                                                 header[field].image_offset = offset - 2;
1632                                                 if(field > 0)
1633                                                         header[field].image_offset -= header[0].next_offset;
1634                                         }
1635                                         len = read_int16(buffer, &offset, buffer_size);
1636                                         len -= 2;
1637                                         break;
1638
1639                                 case M_SOS:
1640                                         header[field].scan_offset = offset - 2;
1641                                         if(field > 0)
1642                                                 header[field].scan_offset -= header[0].next_offset;
1643                                         len = read_int16(buffer, &offset, buffer_size);
1644                                         len -= 2;
1645                                         header[field].data_offset = offset + len;
1646                                         if(field > 0)
1647                                                 header[field].data_offset -= header[0].next_offset;
1648                                         break;
1649
1650 //                              case 0:
1651                                 case M_EOI:
1652                                         if(field > 0)
1653                                         {
1654                                                 header[field].field_size =
1655                                                         header[field].padded_field_size =
1656                                                         offset - header[0].next_offset;
1657                                                 header[field].next_offset = 0;
1658                                         }
1659                                         else
1660                                         {
1661 // Often misses second SOI but gets first EOI
1662 //                                              header[0].next_offset =
1663 //                                                      header[0].padded_field_size =
1664 //                                                      offset;
1665                                         }
1666 //printf("table_offsets M_EOI %d %x\n", field, offset);
1667                                         done = 1;
1668                                         len = 0;
1669                                         break;
1670
1671                                 default:
1672 // Junk appears between fields
1673                                         len = 0;
1674 //                                      len = read_int16(buffer, &offset, buffer_size);
1675 //                                      len -= 2;
1676                                         break;
1677                         }
1678
1679                         if(!done) offset += len;
1680                         if(offset >= buffer_size) done = 1;
1681                 }
1682 //printf("qt_table_offsets 10 %d\n", field);
1683         }
1684
1685         return result;
1686 }
1687
1688 static void insert_quicktime_marker(unsigned char *buffer,
1689         long buffer_size,
1690         long offset,
1691         qt_hdr_t *header)
1692 {
1693         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1694                         ((unsigned long)M_APP1 << 16) |
1695                         (QUICKTIME_MARKER_SIZE - 2));
1696         write_int32(buffer, &offset, buffer_size, 0);
1697         write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1698         write_int32(buffer, &offset, buffer_size, header->field_size);
1699         write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1700         write_int32(buffer, &offset, buffer_size, header->next_offset);
1701         write_int32(buffer, &offset, buffer_size, header->quant_offset);
1702         write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1703         write_int32(buffer, &offset, buffer_size, header->image_offset);
1704         write_int32(buffer, &offset, buffer_size, header->scan_offset);
1705         write_int32(buffer, &offset, buffer_size, header->data_offset);
1706 }
1707
1708
1709 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1710         long *buffer_size,
1711         long *buffer_allocated,
1712         int fields,
1713         long *field2_offset)
1714 {
1715         qt_hdr_t header[2];
1716         int exists = 0;
1717         *field2_offset = -1;
1718
1719         if(fields < 2) return;
1720
1721
1722 // Get offsets for tables in both fields
1723         exists = qt_table_offsets(*buffer, *buffer_size, header);
1724
1725 // APP1 for quicktime already exists
1726         if(exists) return;
1727
1728 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1729 //      header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1730 //if(*field2_offset == 0)
1731 //      fwrite(*buffer, *buffer_size, 1, stdout);
1732
1733
1734
1735         header[0].field_size += QUICKTIME_MARKER_SIZE;
1736         header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1737         header[0].next_offset += QUICKTIME_MARKER_SIZE;
1738         header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1739         header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1740         header[0].image_offset += QUICKTIME_MARKER_SIZE;
1741         header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1742         header[0].data_offset += QUICKTIME_MARKER_SIZE;
1743         header[1].field_size += QUICKTIME_MARKER_SIZE;
1744         header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1745         header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1746         header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1747         header[1].image_offset += QUICKTIME_MARKER_SIZE;
1748         header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1749         header[1].data_offset += QUICKTIME_MARKER_SIZE;
1750         *field2_offset = header[0].next_offset;
1751
1752
1753
1754 // Insert APP1 marker
1755         insert_space(buffer,
1756                 buffer_size,
1757                 buffer_allocated,
1758                 2,
1759                 QUICKTIME_MARKER_SIZE);
1760
1761         insert_quicktime_marker(*buffer,
1762                 *buffer_size,
1763                 2,
1764                 &header[0]);
1765
1766         insert_space(buffer,
1767                 buffer_size,
1768                 buffer_allocated,
1769                 header[0].next_offset + 2,
1770                 QUICKTIME_MARKER_SIZE);
1771
1772         header[1].next_offset = 0;
1773         insert_quicktime_marker(*buffer,
1774                 *buffer_size,
1775                 header[0].next_offset + 2,
1776                 &header[1]);
1777 }
1778
1779
1780 static int avi_table_offsets(unsigned char *buffer,
1781         long buffer_size,
1782         avi_hdr_t *header)
1783 {
1784         int field2 = mjpeg_get_field2(buffer, buffer_size);
1785
1786         header[0].field_number = 1;
1787         header[0].field_size = field2;
1788         header[0].unpadded_field_size = field2;
1789
1790         header[1].field_number = 2;
1791         header[1].field_size = buffer_size - field2;
1792         header[1].unpadded_field_size = buffer_size - field2;
1793         return 0;
1794 }
1795
1796 static void insert_avi_marker(unsigned char *buffer,
1797         long buffer_size,
1798         long offset,
1799         avi_hdr_t *header)
1800 {
1801         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1802                         ((unsigned long)M_APP0 << 16) |
1803                         (AVI_MARKER_SIZE - 2));
1804         write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1805
1806 // One version of McRoweSoft only allows field polarity while
1807 // another version allows field size.
1808         write_char(buffer, &offset, buffer_size, header->field_number);
1809         write_char(buffer, &offset, buffer_size, 0);
1810         write_int32(buffer, &offset, buffer_size, header->field_size);
1811         write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1812 }
1813
1814 void mjpeg_insert_avi_markers(unsigned char **buffer,
1815         long *buffer_size,
1816         long *buffer_allocated,
1817         int fields,
1818         long *field2_offset)
1819 {
1820         avi_hdr_t header[2];
1821         long offset = 0;
1822         *field2_offset = -1;
1823
1824
1825 // Test for existing marker
1826         if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1827         {
1828                 if((*buffer)[offset + 2] == 'A' &&
1829                         (*buffer)[offset + 3] == 'V' &&
1830                         (*buffer)[offset + 4] == 'I' &&
1831                         (*buffer)[offset + 5] == '1')
1832                         return;
1833         }
1834
1835
1836         avi_table_offsets(*buffer, *buffer_size, header);
1837
1838         header[0].field_size += AVI_MARKER_SIZE;
1839         header[0].unpadded_field_size += AVI_MARKER_SIZE;
1840         header[1].field_size += AVI_MARKER_SIZE;
1841         header[1].unpadded_field_size += AVI_MARKER_SIZE;
1842         *field2_offset = header[0].field_size;
1843
1844 // Insert APP0 marker into field 1
1845         insert_space(buffer,
1846                 buffer_size,
1847                 buffer_allocated,
1848                 2,
1849                 AVI_MARKER_SIZE);
1850         insert_avi_marker(*buffer,
1851                 *buffer_size,
1852                 2,
1853                 &header[0]);
1854
1855         insert_space(buffer,
1856                 buffer_size,
1857                 buffer_allocated,
1858                 *field2_offset + 2,
1859                 AVI_MARKER_SIZE);
1860         insert_avi_marker(*buffer,
1861                 *buffer_size,
1862                 *field2_offset + 2,
1863                 &header[1]);
1864
1865
1866
1867 }
1868
1869
1870 static void read_avi_markers(unsigned char *buffer,
1871         long buffer_size,
1872         avi_hdr_t *header)
1873 {
1874         long offset = 0;
1875         int marker_count = 0;
1876         int result = 0;
1877         int marker_size = 0;
1878         while(marker_count < 2 && offset < buffer_size && !result)
1879         {
1880                 result = find_marker(buffer,
1881                         &offset,
1882                         buffer_size,
1883                         M_APP0);
1884                 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1885
1886
1887                 if(!result && marker_size >= 16)
1888                 {
1889 // Marker size, AVI1
1890                         offset += 6;
1891 // field polarity
1892                         header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1893                         read_char(buffer, &offset, buffer_size);
1894                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1895                         header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1896                         marker_count++;
1897                 }
1898         }
1899 }
1900
1901
1902 static void read_quicktime_markers(unsigned char *buffer,
1903         long buffer_size,
1904         qt_hdr_t *header)
1905 {
1906         long offset = 0;
1907         int marker_count = 0;
1908         int result = 0;
1909
1910         while(marker_count < 2 && offset < buffer_size && !result)
1911         {
1912                 result = find_marker(buffer,
1913                         &offset,
1914                         buffer_size,
1915                         M_APP1);
1916
1917                 if(!result)
1918                 {
1919 // Marker size
1920                         read_int16(buffer, &offset, buffer_size);
1921 // Zero
1922                         read_int32(buffer, &offset, buffer_size);
1923 // MJPA
1924                         read_int32(buffer, &offset, buffer_size);
1925 // Information
1926                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1927                         header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1928                         header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1929                         header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1930                         header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1931                         header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1932                         header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1933                         header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1934                         marker_count++;
1935                 }
1936         }
1937 //printf("read_quicktime_markers 1 %d\n", marker_count);
1938 }
1939
1940 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1941 {
1942         qt_hdr_t header[2];
1943         bzero(&header, sizeof(qt_hdr_t) * 2);
1944
1945         read_quicktime_markers(buffer, buffer_size, header);
1946         return header[0].next_offset;
1947 }
1948
1949 long mjpeg_get_avi_field2(unsigned char *buffer,
1950         long buffer_size,
1951         int *field_dominance)
1952 {
1953         avi_hdr_t header[2];
1954         bzero(&header, sizeof(avi_hdr_t) * 2);
1955         read_avi_markers(buffer, buffer_size, header);
1956
1957         *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1958
1959 // One version of McRoweSoft only allows field polarity while
1960 // another version allows field size.
1961         if(header[0].field_size)
1962         {
1963                 return header[0].field_size;
1964         }
1965         else
1966         {
1967                 return mjpeg_get_field2(buffer, buffer_size);
1968         }
1969         return 0;
1970 }
1971
1972 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1973 {
1974         int total_fields = 0;
1975         long field2_offset = 0;
1976         int i;
1977
1978         for(i = 0; i < buffer_size; i++)
1979         {
1980                 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1981                 {
1982                         total_fields++;
1983                         field2_offset = i;
1984                         if(total_fields == 2) break;
1985                 }
1986         }
1987         return field2_offset;
1988 }
1989
1990 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1991 {
1992           long offset = 0;
1993           find_marker(data,
1994                           &offset,
1995                           data_size,
1996                           M_SOF0);
1997           *h = (data[offset + 3] << 8) | (data[offset + 4]);
1998           *w = (data[offset + 5] << 8) | (data[offset + 6]);
1999 }
2000
2001