sketcher rework, plugindialog selection fixes, new ffmpeg plugin.opts/plugin info...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / libmjpeg.C
1 /*
2  * This library is free software; you can redistribute it and/or modify it
3  * under the terms of the GNU Lesser General Public License as published
4  * by the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful, but
8  * WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
15  * USA
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "bccmodels.h"
22 #include "libmjpeg.h"
23
24 /* JPEG MARKERS */
25 #define   M_SOF0    0xc0
26 #define   M_SOF1    0xc1
27 #define   M_SOF2    0xc2
28 #define   M_SOF3    0xc3
29 #define   M_SOF5    0xc5
30 #define   M_SOF6    0xc6
31 #define   M_SOF7    0xc7
32 #define   M_JPG     0xc8
33 #define   M_SOF9    0xc9
34 #define   M_SOF10   0xca
35 #define   M_SOF11   0xcb
36 #define   M_SOF13   0xcd
37 #define   M_SOF14   0xce
38 #define   M_SOF15   0xcf
39 #define   M_DHT     0xc4
40 #define   M_DAC     0xcc
41 #define   M_RST0    0xd0
42 #define   M_RST1    0xd1
43 #define   M_RST2    0xd2
44 #define   M_RST3    0xd3
45 #define   M_RST4    0xd4
46 #define   M_RST5    0xd5
47 #define   M_RST6    0xd6
48 #define   M_RST7    0xd7
49 #define   M_SOI     0xd8
50 #define   M_EOI     0xd9
51 #define   M_SOS     0xda
52 #define   M_DQT     0xdb
53 #define   M_DNL     0xdc
54 #define   M_DRI     0xdd
55 #define   M_DHP     0xde
56 #define   M_EXP     0xdf
57 #define   M_APP0    0xe0
58 #define   M_APP1    0xe1
59 #define   M_APP2    0xe2
60 #define   M_APP3    0xe3
61 #define   M_APP4    0xe4
62 #define   M_APP5    0xe5
63 #define   M_APP6    0xe6
64 #define   M_APP7    0xe7
65 #define   M_APP8    0xe8
66 #define   M_APP9    0xe9
67 #define   M_APP10   0xea
68 #define   M_APP11   0xeb
69 #define   M_APP12   0xec
70 #define   M_APP13   0xed
71 #define   M_APP14   0xee
72 #define   M_APP15   0xef
73 #define   M_JPG0    0xf0
74 #define   M_JPG13   0xfd
75 #define   M_COM     0xfe
76 #define   M_TEM     0x01
77 #define   M_ERROR   0x100
78
79 #define QUICKTIME_MARKER_SIZE 0x2c
80 #define AVI_MARKER_SIZE 0x12
81 #define QUICKTIME_JPEG_TAG 0x6d6a7067
82 #define QUICKTIME_AVI_TAG 0x41564931
83
84
85 METHODDEF(void) mjpeg_error_exit (j_common_ptr cinfo)
86 {
87 /* cinfo->err really points to a mjpeg_error_mgr struct, so coerce pointer */
88         mjpeg_error_ptr mjpegerr = (mjpeg_error_ptr) cinfo->err;
89
90 /* Always display the message. */
91 /* We could postpone this until after returning, if we chose. */
92         (*cinfo->err->output_message) (cinfo);
93
94 /* Return control to the setjmp point */
95         longjmp(mjpegerr->setjmp_buffer, 1);
96 }
97
98 typedef struct
99 {
100         struct jpeg_destination_mgr pub; /* public fields */
101
102         JOCTET *buffer;         /* Pointer to buffer */
103         mjpeg_compressor *engine;
104 } mjpeg_destination_mgr;
105
106 typedef mjpeg_destination_mgr *mjpeg_dest_ptr;
107
108
109 /*
110  * Initialize destination --- called by jpeg_start_compress
111  * before any data is actually written.
112  */
113
114 METHODDEF(void) init_destination(j_compress_ptr cinfo)
115 {
116         mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
117
118 /* Set the pointer to the preallocated buffer */
119         if(!dest->engine->output_buffer)
120         {
121                 dest->engine->output_buffer = new unsigned char[65536];
122                 memset(dest->engine->output_buffer,0,65536);
123                 dest->engine->output_allocated = 65536;
124         }
125         dest->buffer = dest->engine->output_buffer;
126         dest->pub.next_output_byte = dest->engine->output_buffer;
127         dest->pub.free_in_buffer = dest->engine->output_allocated;
128 }
129
130 /*
131  * Empty the output buffer --- called whenever buffer fills up.
132  *
133  * In typical applications, this should write the entire output buffer
134  * (ignoring the current state of next_output_byte & free_in_buffer),
135  * reset the pointer & count to the start of the buffer, and return TRUE
136  * indicating that the buffer has been dumped.
137  *
138  * In applications that need to be able to suspend compression due to output
139  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
140  * In this situation, the compressor will return to its caller (possibly with
141  * an indication that it has not accepted all the supplied scanlines).  The
142  * application should resume compression after it has made more room in the
143  * output buffer.  Note that there are substantial restrictions on the use of
144  * suspension --- see the documentation.
145  *
146  * When suspending, the compressor will back up to a convenient restart point
147  * (typically the start of the current MCU). next_output_byte & free_in_buffer
148  * indicate where the restart point will be if the current call returns FALSE.
149  * Data beyond this point will be regenerated after resumption, so do not
150  * write it out when emptying the buffer externally.
151  */
152
153 METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
154 {
155 /* Allocate a bigger buffer. */
156         mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
157
158         dest->engine->output_size = dest->engine->output_allocated;
159         dest->engine->output_allocated *= 2;
160         unsigned char *new_buffer = new unsigned char[dest->engine->output_allocated];
161         memcpy(new_buffer, dest->engine->output_buffer, dest->engine->output_size);
162         delete [] dest->engine->output_buffer;
163         dest->engine->output_buffer = new_buffer;
164         dest->buffer = dest->engine->output_buffer;
165         dest->pub.next_output_byte = dest->buffer + dest->engine->output_size;
166         dest->pub.free_in_buffer = dest->engine->output_allocated - dest->engine->output_size;
167
168         return TRUE;
169 }
170
171 /*
172  * Terminate destination --- called by jpeg_finish_compress
173  * after all data has been written.  Usually needs to flush buffer.
174  *
175  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
176  * application must deal with any cleanup that should happen even
177  * for error exit.
178  */
179 METHODDEF(void) term_destination(j_compress_ptr cinfo)
180 {
181 /* Just get the length */
182         mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
183         dest->engine->output_size = dest->engine->output_allocated - dest->pub.free_in_buffer;
184 }
185
186 GLOBAL(void) jpeg_buffer_dest(j_compress_ptr cinfo, mjpeg_compressor *engine)
187 {
188         mjpeg_dest_ptr dest;
189
190 /* The destination object is made permanent so that multiple JPEG images
191  * can be written to the same file without re-executing jpeg_stdio_dest.
192  * This makes it dangerous to use this manager and a different destination
193  * manager serially with the same JPEG object, because their private object
194  * sizes may be different.  Caveat programmer.
195  */
196         if(cinfo->dest == NULL)
197         {
198 /* first time for this JPEG object? */
199         cinfo->dest = (struct jpeg_destination_mgr *)
200                 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
201                                 JPOOL_PERMANENT,
202                                 sizeof(mjpeg_destination_mgr));
203         }
204
205         dest = (mjpeg_dest_ptr)cinfo->dest;
206         dest->pub.init_destination = init_destination;
207         dest->pub.empty_output_buffer = empty_output_buffer;
208         dest->pub.term_destination = term_destination;
209         dest->engine = engine;
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 typedef struct {
226         struct jpeg_source_mgr pub;     /* public fields */
227
228         JOCTET * buffer;                /* start of buffer */
229         int bytes;             /* total size of buffer */
230 } mjpeg_source_mgr;
231
232 typedef mjpeg_source_mgr* mjpeg_src_ptr;
233
234 METHODDEF(void) init_source(j_decompress_ptr cinfo)
235 {
236     //mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
237 }
238
239 METHODDEF(boolean) fill_input_buffer(j_decompress_ptr cinfo)
240 {
241         mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
242
243         src->buffer[0] = (JOCTET)0xFF;
244         src->buffer[1] = (JOCTET)M_EOI;
245         src->pub.next_input_byte = src->buffer;
246         src->pub.bytes_in_buffer = 2;
247
248         return TRUE;
249 }
250
251
252 METHODDEF(void) skip_input_data(j_decompress_ptr cinfo, long num_bytes)
253 {
254         mjpeg_src_ptr src = (mjpeg_src_ptr)cinfo->src;
255
256         src->pub.next_input_byte += (size_t)num_bytes;
257         src->pub.bytes_in_buffer -= (size_t)num_bytes;
258 }
259
260
261 METHODDEF(void) term_source(j_decompress_ptr cinfo)
262 {
263 }
264
265 GLOBAL(void) jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long bytes)
266 {
267         mjpeg_src_ptr src;
268
269 /* first time for this JPEG object? */
270         if(cinfo->src == NULL)
271         {
272         cinfo->src = (struct jpeg_source_mgr*)
273                 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
274                         JPOOL_PERMANENT,
275                                         sizeof(mjpeg_source_mgr));
276         src = (mjpeg_src_ptr)cinfo->src;
277         }
278
279         src = (mjpeg_src_ptr)cinfo->src;
280         src->pub.init_source = init_source;
281         src->pub.fill_input_buffer = fill_input_buffer;
282         src->pub.skip_input_data = skip_input_data;
283         src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
284         src->pub.term_source = term_source;
285         src->pub.bytes_in_buffer = bytes;
286         src->pub.next_input_byte = buffer;
287         src->buffer = buffer;
288         src->bytes = bytes;
289 }
290
291 /* JPEG DHT Segment for YCrCb omitted from MJPEG data */
292 static
293 unsigned char jpeg_odml_dht[0x1a4] = {
294     0xff, 0xc4, 0x01, 0xa2,
295
296     0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
298
299     0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
300     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
301
302     0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
303     0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
304     0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
305     0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
306     0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
307     0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
308     0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
309     0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
310     0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
311     0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
312     0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
313     0xf9, 0xfa,
314
315     0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
316     0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
317     0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
318     0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
319     0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
320     0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
321     0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
322     0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
323     0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
324     0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
325     0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
326     0xf9, 0xfa
327 };
328
329
330 /*
331  * Parse the DHT table.
332  * This code comes from jpeg6b (jdmarker.c).
333  */
334 static
335 int jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
336               JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
337 {
338     unsigned int length = (dht[2] << 8) + dht[3] - 2;
339     unsigned int pos = 4;
340     unsigned int count, i;
341     int index;
342
343     JHUFF_TBL **hufftbl;
344     unsigned char bits[17];
345     unsigned char huffval[256];
346
347     while (length > 16)
348     {
349        bits[0] = 0;
350        index = dht[pos++];
351        count = 0;
352        for (i = 1; i <= 16; ++i)
353        {
354            bits[i] = dht[pos++];
355            count += bits[i];
356        }
357        length -= 17;
358
359        if (count > 256 || count > length)
360            return -1;
361
362        for (i = 0; i < count; ++i)
363            huffval[i] = dht[pos++];
364        length -= count;
365
366        if (index & 0x10)
367        {
368            index -= 0x10;
369            hufftbl = &ac_tables[index];
370        }
371        else
372            hufftbl = &dc_tables[index];
373
374        if (index < 0 || index >= NUM_HUFF_TBLS)
375            return -1;
376
377        if (*hufftbl == NULL)
378            *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
379        if (*hufftbl == NULL)
380            return -1;
381
382        memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
383        memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
384     }
385
386     if (length != 0)
387        return -1;
388
389     return 0;
390 }
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406 static void reset_buffer(unsigned char **buffer, long *size, long *allocated)
407 {
408         *size = 0;
409 }
410
411 static void delete_buffer(unsigned char **buffer, long *size, long *allocated)
412 {
413         if(*buffer)
414         {
415                 delete [] *buffer;
416                 *size = 0;
417                 *allocated = 0;
418         }
419 }
420
421 static void append_buffer(unsigned char **buffer,
422         long *size,
423         long *allocated,
424         unsigned char *data,
425         long data_size)
426 {
427         if(!*buffer)
428         {
429                 *buffer = new unsigned char[65536];
430                 memset(*buffer,0,65536);
431                 *size = 0;
432                 *allocated = 65536;
433         }
434
435         if(*size + data_size + 0x100 > *allocated)
436         {
437                 *allocated = *size + data_size + 0x100;
438                 unsigned char *new_buffer = new unsigned char[*allocated];
439                 memcpy(new_buffer, *buffer, *size);
440                 delete [] *buffer;
441                 *buffer = new_buffer;
442         }
443
444         memcpy(*buffer + *size, data, data_size);
445         *size += data_size;
446 }
447
448 static void allocate_temps(mjpeg_t *mjpeg)
449 {
450         int i;
451
452         if(!mjpeg->temp_data)
453     {
454         switch(mjpeg->jpeg_color_model)
455         {
456             case BC_YUV422P:
457 //printf("allocate_temps 1\n");
458                     mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h * 2];
459                     mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
460                     mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h];
461                     mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h];
462                     for(i = 0; i < mjpeg->coded_h; i++)
463                     {
464                             mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
465                             mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w / 2;
466                             mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w / 2 * mjpeg->coded_h + i * mjpeg->coded_w / 2;
467                     }
468                 break;
469
470             case BC_YUV444P:
471                     mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h * 3];
472                     mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
473                     mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h];
474                     mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h];
475                     if(mjpeg->greyscale)
476                                 {
477                                         memset(mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h,
478                                                 0x80,
479                                                 mjpeg->coded_w * mjpeg->coded_h * 2);
480                                 }
481                                 for(i = 0; i < mjpeg->coded_h; i++)
482                     {
483                             mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
484                             mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
485                             mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
486                     }
487                 break;
488
489             case BC_YUV420P:
490                     mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h / 2];
491                     mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
492                     mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h / 2];
493                     mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h / 2];
494                     for(i = 0; i < mjpeg->coded_h; i++)
495                     {
496                             mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
497                             if(i < mjpeg->coded_h / 2)
498                             {
499                                     mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * (mjpeg->coded_w / 2);
500                                     mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + (mjpeg->coded_h / 2) * (mjpeg->coded_w / 2) + i * (mjpeg->coded_w / 2);
501                             }
502                     }
503                 break;
504         }
505     }
506 }
507
508 static int get_input_row(mjpeg_t *mjpeg, mjpeg_compressor *compressor, int i)
509 {
510         int input_row;
511         if(mjpeg->fields > 1)
512                 input_row = i * 2 + compressor->instance;
513         else
514                 input_row = i;
515         if(input_row >= mjpeg->coded_h) input_row = mjpeg->coded_h - 1;
516         return input_row;
517 }
518
519 // Get pointers to rows for the JPEG compressor
520 static void get_rows(mjpeg_t *mjpeg, mjpeg_compressor *compressor)
521 {
522         int i;
523     switch(mjpeg->jpeg_color_model)
524     {
525                 case BC_YUV444P:
526                 {
527                         if(!compressor->rows[0])
528                         {
529                                 compressor->rows[0] = new unsigned char*[compressor->coded_field_h];
530                                 compressor->rows[1] = new unsigned char*[compressor->coded_field_h];
531                                 compressor->rows[2] = new unsigned char*[compressor->coded_field_h];
532                         }
533
534 // User colormodel matches jpeg colormodel
535                         if(mjpeg->color_model == BC_YUV444P &&
536                                 mjpeg->output_w == mjpeg->coded_w &&
537                                 mjpeg->output_h == mjpeg->coded_h)
538                         {
539                                 for(i = 0; i < compressor->coded_field_h; i++)
540                                 {
541                                         int input_row = get_input_row(mjpeg, compressor, i);
542                                         compressor->rows[0][i] = mjpeg->y_argument +
543                                                 mjpeg->coded_w * input_row;
544                                         compressor->rows[1][i] = mjpeg->u_argument +
545                                                 mjpeg->coded_w * input_row;
546                                         compressor->rows[2][i] = mjpeg->v_argument +
547                                                 mjpeg->coded_w * input_row;
548                                 }
549                         }
550                         else
551                         {
552                                 for(i = 0; i < compressor->coded_field_h; i++)
553                                 {
554                                         int input_row = get_input_row(mjpeg, compressor, i);
555                                         compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
556                                         compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
557                                         compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
558                                 }
559                         }
560                         break;
561                 }
562
563                 case BC_YUV422P:
564                 {
565                         if(!compressor->rows[0])
566                         {
567                                 compressor->rows[0] = new unsigned char*[compressor->coded_field_h];
568                                 compressor->rows[1] = new unsigned char*[compressor->coded_field_h];
569                                 compressor->rows[2] = new unsigned char*[compressor->coded_field_h];
570                         }
571
572 // User colormodel matches jpeg colormodel
573                         if(mjpeg->color_model == BC_YUV422P &&
574                                 mjpeg->output_w == mjpeg->coded_w &&
575                                 mjpeg->output_h == mjpeg->coded_h)
576                         {
577                                 for(i = 0; i < compressor->coded_field_h; i++)
578                                 {
579                                         int input_row = get_input_row(mjpeg, compressor, i);
580                                         compressor->rows[0][i] = mjpeg->y_argument +
581                                                 mjpeg->coded_w * input_row;
582                                         compressor->rows[1][i] = mjpeg->u_argument +
583                                                 (mjpeg->coded_w / 2) * input_row;
584                                         compressor->rows[2][i] = mjpeg->v_argument +
585                                                 (mjpeg->coded_w / 2) * input_row;
586                                 }
587                         }
588                         else
589                         {
590                                 for(i = 0; i < compressor->coded_field_h; i++)
591                                 {
592                                         int input_row = get_input_row(mjpeg, compressor, i);
593                                         compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
594                                         compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
595                                         compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
596                                 }
597                         }
598                         break;
599                 }
600
601                 case BC_YUV420P:
602                 {
603                         if(!compressor->rows[0])
604                         {
605                                 compressor->rows[0] = new unsigned char*[mjpeg->coded_h];
606                                 compressor->rows[1] = new unsigned char*[mjpeg->coded_h / 2];
607                                 compressor->rows[2] = new unsigned char*[mjpeg->coded_h / 2];
608                         }
609
610 // User colormodel matches jpeg colormodel
611                         if(mjpeg->color_model == BC_YUV420P &&
612                                 mjpeg->output_w == mjpeg->coded_w &&
613                                 mjpeg->output_h == mjpeg->coded_h)
614                         {
615                                 for(i = 0; i < compressor->coded_field_h; i++)
616                                 {
617                                         int input_row = get_input_row(mjpeg, compressor, i);
618                                         compressor->rows[0][i] = mjpeg->y_argument +
619                                                 mjpeg->coded_w * input_row;
620                         if(i < compressor->coded_field_h / 2)
621                         {
622                                         compressor->rows[1][i] = mjpeg->u_argument +
623                                                 (mjpeg->coded_w / 2) * input_row;
624                                         compressor->rows[2][i] = mjpeg->v_argument +
625                                                 (mjpeg->coded_w / 2) * input_row;
626                         }
627                                 }
628                         }
629                         else
630                         {
631                                 for(i = 0; i < compressor->coded_field_h; i++)
632                                 {
633                                         int input_row = get_input_row(mjpeg, compressor, i);
634                                         compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
635                         if(i < compressor->coded_field_h / 2)
636                         {
637                                         compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
638                                         compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
639                         }
640                                 }
641                         }
642                         break;
643                 }
644         }
645 }
646
647 static void delete_rows(mjpeg_compressor *compressor)
648 {
649         if(compressor->rows[0])
650         {
651                 delete [] compressor->rows[0];
652                 delete [] compressor->rows[1];
653                 delete [] compressor->rows[2];
654         }
655 }
656
657 /* replacement routine to suppress decompress warnings */
658 static void mjpeg_emit_message(j_common_ptr cinfo, int msg_level)
659 {
660   struct jpeg_error_mgr * err = cinfo->err;
661   if (msg_level < 0) {
662     err->num_warnings++;
663     if(err->trace_level >= 3)
664       (*err->output_message) (cinfo);
665   } else {
666     if (err->trace_level >= msg_level)
667       (*err->output_message) (cinfo);
668   }
669 }
670
671 static void new_jpeg_objects(mjpeg_compressor *engine)
672 {
673         engine->jpeg_decompress.err = jpeg_std_error(&(engine->jpeg_error.pub));
674         engine->jpeg_error.pub.error_exit = mjpeg_error_exit;
675         engine->jpeg_error.pub.emit_message = mjpeg_emit_message;
676 /* Ideally the error handler would be set here but it must be called in a thread */
677         jpeg_create_decompress(&(engine->jpeg_decompress));
678         engine->jpeg_decompress.raw_data_out = TRUE;
679 #if JPEG_LIB_VERSION >= 70
680         engine->jpeg_decompress.do_fancy_upsampling = FALSE;
681 #endif
682         engine->jpeg_decompress.dct_method = JDCT_IFAST;
683 }
684
685 static void delete_jpeg_objects(mjpeg_compressor *engine)
686 {
687         jpeg_destroy_decompress(&(engine->jpeg_decompress));
688 }
689
690
691
692 static void unlock_compress_loop(mjpeg_compressor *engine)
693 {
694         pthread_mutex_unlock(&(engine->input_lock));
695 }
696
697 static void lock_compress_loop(mjpeg_compressor *engine)
698 {
699         pthread_mutex_lock(&(engine->output_lock));
700 }
701
702 // Make temp rows for compressor
703 static void get_mcu_rows(mjpeg_t *mjpeg,
704         mjpeg_compressor *engine,
705         int start_row)
706 {
707         int i, j, scanline, lastline;
708         for(i = 0; i < 3; i++)
709         {
710                 for(j = 0; j < 16; j++)
711                 {
712                         scanline = start_row;
713                         lastline = engine->coded_field_h;
714                         if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) {
715                                 lastline /= 2;  scanline /= 2;
716                         }
717                         scanline += j;
718                         if(scanline >= lastline) scanline = lastline - 1;
719                         engine->mcu_rows[i][j] = engine->rows[i][scanline];
720                 }
721         }
722 }
723
724
725 static void decompress_field(mjpeg_compressor *engine)
726 {
727         mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
728         long buffer_offset = engine->instance * mjpeg->input_field2;
729         unsigned char *buffer = mjpeg->input_data + buffer_offset;
730         long buffer_size;
731
732 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
733         if(engine->instance == 0 && mjpeg->fields > 1)
734                 buffer_size = mjpeg->input_field2 - buffer_offset;
735         else
736                 buffer_size = mjpeg->input_size - buffer_offset;
737
738         mjpeg->error = 0;
739
740         if(setjmp(engine->jpeg_error.setjmp_buffer))
741         {
742 /* If we get here, the JPEG code has signaled an error. */
743 printf("decompress_field %d\n", __LINE__);
744                 delete_jpeg_objects(engine);
745 printf("decompress_field %d\n", __LINE__);
746                 new_jpeg_objects(engine);
747 printf("decompress_field %d\n", __LINE__);
748                 mjpeg->error = 1;
749 printf("decompress_field %d\n", __LINE__);
750                 goto finish;
751         }
752
753 //printf("decompress_field 2\n");
754         jpeg_buffer_src(&engine->jpeg_decompress,
755                 buffer,
756                 buffer_size);
757         jpeg_read_header(&engine->jpeg_decompress, TRUE);
758
759         if ( engine->jpeg_decompress.ac_huff_tbl_ptrs[0] == NULL &&
760              engine->jpeg_decompress.ac_huff_tbl_ptrs[1] == NULL &&
761              engine->jpeg_decompress.dc_huff_tbl_ptrs[0] == NULL &&
762              engine->jpeg_decompress.dc_huff_tbl_ptrs[1] == NULL )
763                 jpeg_load_dht(  &engine->jpeg_decompress,
764                                 jpeg_odml_dht,
765                                 engine->jpeg_decompress.ac_huff_tbl_ptrs,
766                                 engine->jpeg_decompress.dc_huff_tbl_ptrs );
767 // Reset by jpeg_read_header
768         engine->jpeg_decompress.raw_data_out = TRUE;
769 #if JPEG_LIB_VERSION >= 70
770         engine->jpeg_decompress.do_fancy_upsampling = FALSE;
771 #endif
772         jpeg_start_decompress(&engine->jpeg_decompress);
773
774 // Generate colormodel from jpeg sampling
775         if( engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
776             engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
777                 mjpeg->jpeg_color_model = BC_YUV420P;
778         else if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 1 &&
779             engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
780                 mjpeg->jpeg_color_model = BC_YUV422P;
781         else
782                 mjpeg->jpeg_color_model = BC_YUV444P;
783
784         if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE)
785                 mjpeg->greyscale = 1;
786
787 //printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor);
788 // Must be here because the color model isn't known until now
789         pthread_mutex_lock(&(mjpeg->decompress_init));
790         allocate_temps(mjpeg);
791         pthread_mutex_unlock(&(mjpeg->decompress_init));
792         get_rows(mjpeg, engine);
793
794 //printf("decompress_field 30\n");
795
796         while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
797         {
798                 get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
799                 jpeg_read_raw_data(&engine->jpeg_decompress,
800                         engine->mcu_rows,
801                         engine->coded_field_h);
802         }
803         jpeg_finish_decompress(&engine->jpeg_decompress);
804
805 //printf("decompress_field 40\n");
806
807 finish:
808         ;
809 }
810
811 void mjpeg_decompress_loop(mjpeg_compressor *engine)
812 {
813         while(!engine->done)
814         {
815                 pthread_mutex_lock(&engine->input_lock);
816                 if(!engine->done)
817                 {
818                         decompress_field(engine);
819                 }
820                 pthread_mutex_unlock(&(engine->output_lock));
821         }
822 }
823
824
825 static void compress_field(mjpeg_compressor *engine)
826 {
827         mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
828
829 //printf("compress_field 1\n");
830         get_rows(mjpeg, engine);
831         reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
832         jpeg_buffer_dest(&engine->jpeg_compress, engine);
833
834
835         engine->jpeg_compress.raw_data_in = TRUE;
836 #if JPEG_LIB_VERSION >= 70
837         engine->jpeg_compress.do_fancy_downsampling = FALSE;
838 #endif
839         jpeg_start_compress(&engine->jpeg_compress, TRUE);
840
841         while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
842         {
843                 get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
844
845                 jpeg_write_raw_data(&engine->jpeg_compress,
846                         engine->mcu_rows,
847                         engine->coded_field_h);
848         }
849         jpeg_finish_compress(&engine->jpeg_compress);
850 //printf("compress_field 2\n");
851 }
852
853
854 void mjpeg_compress_loop(mjpeg_compressor *engine)
855 {
856         while(!engine->done)
857         {
858                 pthread_mutex_lock(&engine->input_lock);
859                 if(!engine->done)
860                 {
861                         compress_field(engine);
862                 }
863                 pthread_mutex_unlock(&engine->output_lock);
864         }
865 }
866
867 static void delete_temps(mjpeg_t *mjpeg)
868 {
869         if(mjpeg->temp_data)
870     {
871             delete [] mjpeg->temp_data;
872             delete [] mjpeg->temp_rows[0];
873             delete [] mjpeg->temp_rows[1];
874             delete [] mjpeg->temp_rows[2];
875                 mjpeg->temp_data = 0;
876         }
877 }
878
879 mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
880 {
881         mjpeg_compressor *result = new mjpeg_compressor();
882         memset(result, 0, sizeof(mjpeg_compressor));
883         pthread_attr_t  attr;
884         pthread_mutexattr_t mutex_attr;
885
886         result->mjpeg = mjpeg;
887         result->instance = instance;
888         new_jpeg_objects(result);
889         result->field_h = mjpeg->output_h / mjpeg->fields;
890         result->coded_field_h = (result->field_h % 16) ?
891                 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
892
893         result->mcu_rows[0] = new unsigned char *[16];
894         result->mcu_rows[1] = new unsigned char *[16];
895         result->mcu_rows[2] = new unsigned char *[16];
896
897         pthread_mutexattr_init(&mutex_attr);
898 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
899         pthread_mutex_init(&(result->input_lock), &mutex_attr);
900         pthread_mutex_lock(&(result->input_lock));
901         pthread_mutex_init(&(result->output_lock), &mutex_attr);
902         pthread_mutex_lock(&(result->output_lock));
903
904         pthread_attr_init(&attr);
905         pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_decompress_loop, result);
906
907         return result;
908 }
909
910 void mjpeg_delete_decompressor(mjpeg_compressor *engine)
911 {
912         engine->done = 1;
913         pthread_mutex_unlock(&(engine->input_lock));
914         pthread_join(engine->tid, 0);
915         pthread_mutex_destroy(&(engine->input_lock));
916         pthread_mutex_destroy(&(engine->output_lock));
917         jpeg_destroy_decompress(&(engine->jpeg_decompress));
918         delete_rows(engine);
919         delete [] engine->mcu_rows[0];
920         delete [] engine->mcu_rows[1];
921         delete [] engine->mcu_rows[2];
922         delete engine;
923 }
924
925 mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
926 {
927         pthread_attr_t  attr;
928         pthread_mutexattr_t mutex_attr;
929         mjpeg_compressor *result = new mjpeg_compressor();
930         memset(result, 0, sizeof(mjpeg_compressor));
931
932         result->field_h = mjpeg->output_h / mjpeg->fields;
933         result->coded_field_h = (result->field_h % 16) ?
934                 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
935         result->mjpeg = mjpeg;
936         result->instance = instance;
937         result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
938         jpeg_create_compress(&(result->jpeg_compress));
939         result->jpeg_compress.image_width = mjpeg->output_w;
940         result->jpeg_compress.image_height = result->field_h;
941         result->jpeg_compress.input_components = 3;
942         result->jpeg_compress.in_color_space = JCS_RGB;
943         jpeg_set_defaults(&(result->jpeg_compress));
944         result->jpeg_compress.input_components = 3;
945         result->jpeg_compress.in_color_space = JCS_RGB;
946         jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
947
948         if(mjpeg->use_float)
949                 result->jpeg_compress.dct_method = JDCT_FLOAT;
950         else
951                 result->jpeg_compress.dct_method = JDCT_IFAST;
952 //              result->jpeg_compress.dct_method = JDCT_ISLOW;
953
954 /* Fix sampling */
955         switch(mjpeg->fields)
956     {
957         case 1:
958                 mjpeg->jpeg_color_model = BC_YUV420P;
959                     result->jpeg_compress.comp_info[0].h_samp_factor = 2;
960                     result->jpeg_compress.comp_info[0].v_samp_factor = 2;
961                     result->jpeg_compress.comp_info[1].h_samp_factor = 1;
962                     result->jpeg_compress.comp_info[1].v_samp_factor = 1;
963                     result->jpeg_compress.comp_info[2].h_samp_factor = 1;
964                     result->jpeg_compress.comp_info[2].v_samp_factor = 1;
965                 break;
966         case 2:
967                 mjpeg->jpeg_color_model = BC_YUV422P;
968                     result->jpeg_compress.comp_info[0].h_samp_factor = 2;
969                     result->jpeg_compress.comp_info[0].v_samp_factor = 1;
970                     result->jpeg_compress.comp_info[1].h_samp_factor = 1;
971                     result->jpeg_compress.comp_info[1].v_samp_factor = 1;
972                     result->jpeg_compress.comp_info[2].h_samp_factor = 1;
973                     result->jpeg_compress.comp_info[2].v_samp_factor = 1;
974                 break;
975     }
976     allocate_temps(mjpeg);
977
978         result->mcu_rows[0] = new unsigned char *[16];
979         result->mcu_rows[1] = new unsigned char *[16];
980         result->mcu_rows[2] = new unsigned char *[16];
981
982         pthread_mutexattr_init(&mutex_attr);
983 //      pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
984         pthread_mutex_init(&(result->input_lock), &mutex_attr);
985         pthread_mutex_lock(&(result->input_lock));
986         pthread_mutex_init(&(result->output_lock), &mutex_attr);
987         pthread_mutex_lock(&(result->output_lock));
988
989         pthread_attr_init(&attr);
990         pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_compress_loop, result);
991         return result;
992 }
993
994
995 void mjpeg_delete_compressor(mjpeg_compressor *engine)
996 {
997         engine->done = 1;
998         pthread_mutex_unlock(&(engine->input_lock));
999         pthread_join(engine->tid, 0);
1000         pthread_mutex_destroy(&(engine->input_lock));
1001         pthread_mutex_destroy(&(engine->output_lock));
1002         jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
1003         if(engine->output_buffer) delete [] engine->output_buffer;
1004         delete_rows(engine);
1005         delete [] engine->mcu_rows[0];
1006         delete [] engine->mcu_rows[1];
1007         delete [] engine->mcu_rows[2];
1008         delete engine;
1009 }
1010
1011 unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
1012 {
1013         return mjpeg->output_data;
1014 }
1015
1016 long mjpeg_output_field2(mjpeg_t *mjpeg)
1017 {
1018         return mjpeg->output_field2;
1019 }
1020
1021 long mjpeg_output_size(mjpeg_t *mjpeg)
1022 {
1023         return mjpeg->output_size;
1024 }
1025
1026 long mjpeg_output_allocated(mjpeg_t *mjpeg)
1027 {
1028         return mjpeg->output_allocated;
1029 }
1030
1031 void mjpeg_set_output_size(mjpeg_t *mjpeg, long output_size)
1032 {
1033         mjpeg->output_size = output_size;
1034 }
1035
1036
1037 int mjpeg_compress(mjpeg_t *mjpeg,
1038         unsigned char **row_pointers,
1039         unsigned char *y_plane,
1040         unsigned char *u_plane,
1041         unsigned char *v_plane,
1042         int color_model,
1043         int cpus)
1044 {
1045         int i, result = 0;
1046         int corrected_fields = mjpeg->fields;
1047         mjpeg->color_model = color_model;
1048         mjpeg->cpus = cpus;
1049
1050 //printf("mjpeg_compress 1 %d\n", color_model);
1051 /* Reset output buffer */
1052         reset_buffer(&mjpeg->output_data,
1053                 &mjpeg->output_size,
1054                 &mjpeg->output_allocated);
1055
1056 /* Create compression engines as needed */
1057         for(i = 0; i < mjpeg->fields; i++)
1058         {
1059                 if(!mjpeg->compressors[i])
1060                 {
1061                         mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
1062                 }
1063         }
1064
1065 /* Arm YUV buffers */
1066         mjpeg->row_argument = row_pointers;
1067         mjpeg->y_argument = y_plane;
1068         mjpeg->u_argument = u_plane;
1069         mjpeg->v_argument = v_plane;
1070 // User colormodel doesn't match encoder colormodel
1071 // Copy to interlacing buffer first
1072         if(mjpeg->color_model != mjpeg->jpeg_color_model ||
1073                 mjpeg->output_w != mjpeg->coded_w ||
1074                 mjpeg->output_h != mjpeg->coded_h)
1075         {
1076 /*
1077  * printf("mjpeg_compress %d %d %d %d\n",
1078  * mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_h);
1079  */
1080                 BC_CModels::transfer(0,
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
1532 static int qt_table_offsets(unsigned char *buffer,
1533         long buffer_size,
1534         qt_hdr_t *header)
1535 {
1536         int done = 0;
1537         long offset = 0;
1538         int marker = 0;
1539         int field = 0;
1540         int len;
1541         int result = 0;
1542
1543         bzero(header, sizeof(qt_hdr_t) * 2);
1544
1545 // Read every marker to get the offsets for the headers
1546         for(field = 0; field < 2; field++)
1547         {
1548                 done = 0;
1549
1550                 while(!done)
1551                 {
1552                         marker = next_marker(buffer,
1553                                 &offset,
1554                                 buffer_size);
1555
1556                         len = 0;
1557
1558                         switch(marker)
1559                         {
1560                                 case M_SOI:
1561 // The first field may be padded
1562                                         if(field > 0)
1563                                         {
1564                                                 header[0].next_offset =
1565                                                         header[0].padded_field_size =
1566                                                         offset - 2;
1567                                         }
1568                                         len = 0;
1569                                         break;
1570
1571                                 case M_APP1:
1572 // Quicktime marker already exists.  Abort.
1573                                         if(buffer[offset + 6] == 'm' &&
1574                                                 buffer[offset + 7] == 'j' &&
1575                                                 buffer[offset + 8] == 'p' &&
1576                                                 buffer[offset + 9] == 'a')
1577                                         {
1578                                                 result = 1;
1579                                                 done = 1;
1580                                         }
1581                                         break;
1582
1583                                 case M_DQT:
1584                                         if(!header[field].quant_offset)
1585                                         {
1586                                                 header[field].quant_offset = offset - 2;
1587                                                 if(field > 0)
1588                                                         header[field].quant_offset -= header[0].next_offset;
1589                                         }
1590                                         len = read_int16(buffer, &offset, buffer_size);
1591                                         len -= 2;
1592                                         break;
1593
1594                                 case M_DHT:
1595                                         if(!header[field].huffman_offset)
1596                                         {
1597                                                 header[field].huffman_offset = offset - 2;
1598                                                 if(field > 0)
1599                                                         header[field].huffman_offset -= header[0].next_offset;
1600                                         }
1601                                         len = read_int16(buffer, &offset, buffer_size);
1602                                         len -= 2;
1603                                         break;
1604
1605                                 case M_SOF0:
1606                                         if(!header[field].image_offset)
1607                                         {
1608                                                 header[field].image_offset = offset - 2;
1609                                                 if(field > 0)
1610                                                         header[field].image_offset -= header[0].next_offset;
1611                                         }
1612                                         len = read_int16(buffer, &offset, buffer_size);
1613                                         len -= 2;
1614                                         break;
1615
1616                                 case M_SOS:
1617                                         header[field].scan_offset = offset - 2;
1618                                         if(field > 0)
1619                                                 header[field].scan_offset -= header[0].next_offset;
1620                                         len = read_int16(buffer, &offset, buffer_size);
1621                                         len -= 2;
1622                                         header[field].data_offset = offset + len;
1623                                         if(field > 0)
1624                                                 header[field].data_offset -= header[0].next_offset;
1625                                         break;
1626
1627 //                              case 0:
1628                                 case M_EOI:
1629                                         if(field > 0)
1630                                         {
1631                                                 header[field].field_size =
1632                                                         header[field].padded_field_size =
1633                                                         offset - header[0].next_offset;
1634                                                 header[field].next_offset = 0;
1635                                         }
1636                                         else
1637                                         {
1638 // Often misses second SOI but gets first EOI
1639 //                                              header[0].next_offset =
1640 //                                                      header[0].padded_field_size =
1641 //                                                      offset;
1642                                         }
1643 //printf("table_offsets M_EOI %d %x\n", field, offset);
1644                                         done = 1;
1645                                         len = 0;
1646                                         break;
1647
1648                                 default:
1649 // Junk appears between fields
1650                                         len = 0;
1651 //                                      len = read_int16(buffer, &offset, buffer_size);
1652 //                                      len -= 2;
1653                                         break;
1654                         }
1655
1656                         if(!done) offset += len;
1657                         if(offset >= buffer_size) done = 1;
1658                 }
1659 //printf("qt_table_offsets 10 %d\n", field);
1660         }
1661
1662         return result;
1663 }
1664
1665 static void insert_quicktime_marker(unsigned char *buffer,
1666         long buffer_size,
1667         long offset,
1668         qt_hdr_t *header)
1669 {
1670         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1671                         ((unsigned long)M_APP1 << 16) |
1672                         (QUICKTIME_MARKER_SIZE - 2));
1673         write_int32(buffer, &offset, buffer_size, 0);
1674         write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1675         write_int32(buffer, &offset, buffer_size, header->field_size);
1676         write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1677         write_int32(buffer, &offset, buffer_size, header->next_offset);
1678         write_int32(buffer, &offset, buffer_size, header->quant_offset);
1679         write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1680         write_int32(buffer, &offset, buffer_size, header->image_offset);
1681         write_int32(buffer, &offset, buffer_size, header->scan_offset);
1682         write_int32(buffer, &offset, buffer_size, header->data_offset);
1683 }
1684
1685
1686 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1687         long *buffer_size,
1688         long *buffer_allocated,
1689         int fields,
1690         long *field2_offset)
1691 {
1692         qt_hdr_t header[2];
1693         int exists = 0;
1694         *field2_offset = -1;
1695
1696         if(fields < 2) return;
1697
1698
1699 // Get offsets for tables in both fields
1700         exists = qt_table_offsets(*buffer, *buffer_size, header);
1701
1702 // APP1 for quicktime already exists
1703         if(exists) return;
1704
1705 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1706 //      header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1707 //if(*field2_offset == 0)
1708 //      fwrite(*buffer, *buffer_size, 1, stdout);
1709
1710
1711
1712         header[0].field_size += QUICKTIME_MARKER_SIZE;
1713         header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1714         header[0].next_offset += QUICKTIME_MARKER_SIZE;
1715         header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1716         header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1717         header[0].image_offset += QUICKTIME_MARKER_SIZE;
1718         header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1719         header[0].data_offset += QUICKTIME_MARKER_SIZE;
1720         header[1].field_size += QUICKTIME_MARKER_SIZE;
1721         header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1722         header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1723         header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1724         header[1].image_offset += QUICKTIME_MARKER_SIZE;
1725         header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1726         header[1].data_offset += QUICKTIME_MARKER_SIZE;
1727         *field2_offset = header[0].next_offset;
1728
1729
1730
1731 // Insert APP1 marker
1732         insert_space(buffer,
1733                 buffer_size,
1734                 buffer_allocated,
1735                 2,
1736                 QUICKTIME_MARKER_SIZE);
1737
1738         insert_quicktime_marker(*buffer,
1739                 *buffer_size,
1740                 2,
1741                 &header[0]);
1742
1743         insert_space(buffer,
1744                 buffer_size,
1745                 buffer_allocated,
1746                 header[0].next_offset + 2,
1747                 QUICKTIME_MARKER_SIZE);
1748
1749         header[1].next_offset = 0;
1750         insert_quicktime_marker(*buffer,
1751                 *buffer_size,
1752                 header[0].next_offset + 2,
1753                 &header[1]);
1754 }
1755
1756
1757 static int avi_table_offsets(unsigned char *buffer,
1758         long buffer_size,
1759         avi_hdr_t *header)
1760 {
1761         int field2 = mjpeg_get_field2(buffer, buffer_size);
1762
1763         header[0].field_number = 1;
1764         header[0].field_size = field2;
1765         header[0].unpadded_field_size = field2;
1766
1767         header[1].field_number = 2;
1768         header[1].field_size = buffer_size - field2;
1769         header[1].unpadded_field_size = buffer_size - field2;
1770         return 0;
1771 }
1772
1773 static void insert_avi_marker(unsigned char *buffer,
1774         long buffer_size,
1775         long offset,
1776         avi_hdr_t *header)
1777 {
1778         write_int32(buffer, &offset, buffer_size, 0xff000000 |
1779                         ((unsigned long)M_APP0 << 16) |
1780                         (AVI_MARKER_SIZE - 2));
1781         write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1782
1783 // One version of McRoweSoft only allows field polarity while
1784 // another version allows field size.
1785         write_char(buffer, &offset, buffer_size, header->field_number);
1786         write_char(buffer, &offset, buffer_size, 0);
1787         write_int32(buffer, &offset, buffer_size, header->field_size);
1788         write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1789 }
1790
1791 void mjpeg_insert_avi_markers(unsigned char **buffer,
1792         long *buffer_size,
1793         long *buffer_allocated,
1794         int fields,
1795         long *field2_offset)
1796 {
1797         avi_hdr_t header[2];
1798         long offset = 0;
1799         *field2_offset = -1;
1800
1801
1802 // Test for existing marker
1803         if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1804         {
1805                 if((*buffer)[offset + 2] == 'A' &&
1806                         (*buffer)[offset + 3] == 'V' &&
1807                         (*buffer)[offset + 4] == 'I' &&
1808                         (*buffer)[offset + 5] == '1')
1809                         return;
1810         }
1811
1812
1813         avi_table_offsets(*buffer, *buffer_size, header);
1814
1815         header[0].field_size += AVI_MARKER_SIZE;
1816         header[0].unpadded_field_size += AVI_MARKER_SIZE;
1817         header[1].field_size += AVI_MARKER_SIZE;
1818         header[1].unpadded_field_size += AVI_MARKER_SIZE;
1819         *field2_offset = header[0].field_size;
1820
1821 // Insert APP0 marker into field 1
1822         insert_space(buffer,
1823                 buffer_size,
1824                 buffer_allocated,
1825                 2,
1826                 AVI_MARKER_SIZE);
1827         insert_avi_marker(*buffer,
1828                 *buffer_size,
1829                 2,
1830                 &header[0]);
1831
1832         insert_space(buffer,
1833                 buffer_size,
1834                 buffer_allocated,
1835                 *field2_offset + 2,
1836                 AVI_MARKER_SIZE);
1837         insert_avi_marker(*buffer,
1838                 *buffer_size,
1839                 *field2_offset + 2,
1840                 &header[1]);
1841
1842
1843
1844 }
1845
1846
1847 static void read_avi_markers(unsigned char *buffer,
1848         long buffer_size,
1849         avi_hdr_t *header)
1850 {
1851         long offset = 0;
1852         int marker_count = 0;
1853         int result = 0;
1854         int marker_size = 0;
1855         while(marker_count < 2 && offset < buffer_size && !result)
1856         {
1857                 result = find_marker(buffer,
1858                         &offset,
1859                         buffer_size,
1860                         M_APP0);
1861                 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1862
1863
1864                 if(!result && marker_size >= 16)
1865                 {
1866 // Marker size, AVI1
1867                         offset += 6;
1868 // field polarity
1869                         header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1870                         read_char(buffer, &offset, buffer_size);
1871                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1872                         header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1873                         marker_count++;
1874                 }
1875         }
1876 }
1877
1878
1879 static void read_quicktime_markers(unsigned char *buffer,
1880         long buffer_size,
1881         qt_hdr_t *header)
1882 {
1883         long offset = 0;
1884         int marker_count = 0;
1885         int result = 0;
1886
1887         while(marker_count < 2 && offset < buffer_size && !result)
1888         {
1889                 result = find_marker(buffer,
1890                         &offset,
1891                         buffer_size,
1892                         M_APP1);
1893
1894                 if(!result)
1895                 {
1896 // Marker size
1897                         read_int16(buffer, &offset, buffer_size);
1898 // Zero
1899                         read_int32(buffer, &offset, buffer_size);
1900 // MJPA
1901                         read_int32(buffer, &offset, buffer_size);
1902 // Information
1903                         header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1904                         header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1905                         header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1906                         header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1907                         header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1908                         header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1909                         header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1910                         header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1911                         marker_count++;
1912                 }
1913         }
1914 //printf("read_quicktime_markers 1 %d\n", marker_count);
1915 }
1916
1917 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1918 {
1919         qt_hdr_t header[2];
1920         bzero(&header, sizeof(qt_hdr_t) * 2);
1921
1922         read_quicktime_markers(buffer, buffer_size, header);
1923         return header[0].next_offset;
1924 }
1925
1926 long mjpeg_get_avi_field2(unsigned char *buffer,
1927         long buffer_size,
1928         int *field_dominance)
1929 {
1930         avi_hdr_t header[2];
1931         bzero(&header, sizeof(avi_hdr_t) * 2);
1932         read_avi_markers(buffer, buffer_size, header);
1933
1934         *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1935
1936 // One version of McRoweSoft only allows field polarity while
1937 // another version allows field size.
1938         if(header[0].field_size)
1939         {
1940                 return header[0].field_size;
1941         }
1942         else
1943         {
1944                 return mjpeg_get_field2(buffer, buffer_size);
1945         }
1946         return 0;
1947 }
1948
1949 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1950 {
1951         int total_fields = 0;
1952         long field2_offset = 0;
1953         int i;
1954
1955         for(i = 0; i < buffer_size; i++)
1956         {
1957                 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1958                 {
1959                         total_fields++;
1960                         field2_offset = i;
1961                         if(total_fields == 2) break;
1962                 }
1963         }
1964         return field2_offset;
1965 }
1966
1967 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1968 {
1969           long offset = 0;
1970           find_marker(data,
1971                           &offset,
1972                           data_size,
1973                           M_SOF0);
1974           *h = (data[offset + 3] << 8) | (data[offset + 4]);
1975           *w = (data[offset + 5] << 8) | (data[offset + 6]);
1976 }
1977
1978