00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include "colormodels.h"
00021 #include "libmjpeg.h"
00022
00023
00024 #define M_SOF0 0xc0
00025 #define M_SOF1 0xc1
00026 #define M_SOF2 0xc2
00027 #define M_SOF3 0xc3
00028 #define M_SOF5 0xc5
00029 #define M_SOF6 0xc6
00030 #define M_SOF7 0xc7
00031 #define M_JPG 0xc8
00032 #define M_SOF9 0xc9
00033 #define M_SOF10 0xca
00034 #define M_SOF11 0xcb
00035 #define M_SOF13 0xcd
00036 #define M_SOF14 0xce
00037 #define M_SOF15 0xcf
00038 #define M_DHT 0xc4
00039 #define M_DAC 0xcc
00040 #define M_RST0 0xd0
00041 #define M_RST1 0xd1
00042 #define M_RST2 0xd2
00043 #define M_RST3 0xd3
00044 #define M_RST4 0xd4
00045 #define M_RST5 0xd5
00046 #define M_RST6 0xd6
00047 #define M_RST7 0xd7
00048 #define M_SOI 0xd8
00049 #define M_EOI 0xd9
00050 #define M_SOS 0xda
00051 #define M_DQT 0xdb
00052 #define M_DNL 0xdc
00053 #define M_DRI 0xdd
00054 #define M_DHP 0xde
00055 #define M_EXP 0xdf
00056 #define M_APP0 0xe0
00057 #define M_APP1 0xe1
00058 #define M_APP2 0xe2
00059 #define M_APP3 0xe3
00060 #define M_APP4 0xe4
00061 #define M_APP5 0xe5
00062 #define M_APP6 0xe6
00063 #define M_APP7 0xe7
00064 #define M_APP8 0xe8
00065 #define M_APP9 0xe9
00066 #define M_APP10 0xea
00067 #define M_APP11 0xeb
00068 #define M_APP12 0xec
00069 #define M_APP13 0xed
00070 #define M_APP14 0xee
00071 #define M_APP15 0xef
00072 #define M_JPG0 0xf0
00073 #define M_JPG13 0xfd
00074 #define M_COM 0xfe
00075 #define M_TEM 0x01
00076 #define M_ERROR 0x100
00077
00078 #define QUICKTIME_MARKER_SIZE 0x2c
00079 #define AVI_MARKER_SIZE 0x12
00080 #define QUICKTIME_JPEG_TAG 0x6d6a7067
00081 #define QUICKTIME_AVI_TAG 0x41564931
00082
00083
00084 METHODDEF(void) mjpeg_error_exit (j_common_ptr cinfo)
00085 {
00086
00087 mjpeg_error_ptr mjpegerr = (mjpeg_error_ptr) cinfo->err;
00088
00089
00090
00091 (*cinfo->err->output_message) (cinfo);
00092
00093
00094 longjmp(mjpegerr->setjmp_buffer, 1);
00095 }
00096
00097 typedef struct
00098 {
00099 struct jpeg_destination_mgr pub;
00100
00101 JOCTET *buffer;
00102 mjpeg_compressor *engine;
00103 } mjpeg_destination_mgr;
00104
00105 typedef mjpeg_destination_mgr *mjpeg_dest_ptr;
00106
00107
00108
00109
00110
00111
00112
00113 METHODDEF(void) init_destination(j_compress_ptr cinfo)
00114 {
00115 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
00116
00117
00118 if(!dest->engine->output_buffer)
00119 {
00120 dest->engine->output_buffer = calloc(1, 65536);
00121 dest->engine->output_allocated = 65536;
00122 }
00123 dest->buffer = dest->engine->output_buffer;
00124 dest->pub.next_output_byte = dest->engine->output_buffer;
00125 dest->pub.free_in_buffer = dest->engine->output_allocated;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
00152 {
00153
00154 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
00155
00156 dest->engine->output_size = dest->engine->output_allocated;
00157 dest->engine->output_allocated *= 2;
00158 dest->engine->output_buffer = realloc(dest->engine->output_buffer,
00159 dest->engine->output_allocated);
00160 dest->buffer = dest->engine->output_buffer;
00161 dest->pub.next_output_byte = dest->buffer + dest->engine->output_size;
00162 dest->pub.free_in_buffer = dest->engine->output_allocated - dest->engine->output_size;
00163
00164 return TRUE;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 METHODDEF(void) term_destination(j_compress_ptr cinfo)
00176 {
00177
00178 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
00179 dest->engine->output_size = dest->engine->output_allocated - dest->pub.free_in_buffer;
00180 }
00181
00182 GLOBAL(void) jpeg_buffer_dest(j_compress_ptr cinfo, mjpeg_compressor *engine)
00183 {
00184 mjpeg_dest_ptr dest;
00185
00186
00187
00188
00189
00190
00191
00192 if(cinfo->dest == NULL)
00193 {
00194
00195 cinfo->dest = (struct jpeg_destination_mgr *)
00196 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
00197 JPOOL_PERMANENT,
00198 sizeof(mjpeg_destination_mgr));
00199 }
00200
00201 dest = (mjpeg_dest_ptr)cinfo->dest;
00202 dest->pub.init_destination = init_destination;
00203 dest->pub.empty_output_buffer = empty_output_buffer;
00204 dest->pub.term_destination = term_destination;
00205 dest->engine = engine;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 typedef struct {
00222 struct jpeg_source_mgr pub;
00223
00224 JOCTET * buffer;
00225 int bytes;
00226 } mjpeg_source_mgr;
00227
00228 typedef mjpeg_source_mgr* mjpeg_src_ptr;
00229
00230 METHODDEF(void) init_source(j_decompress_ptr cinfo)
00231 {
00232 mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
00233 }
00234
00235 METHODDEF(boolean) fill_input_buffer(j_decompress_ptr cinfo)
00236 {
00237 mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
00238
00239 src->buffer[0] = (JOCTET)0xFF;
00240 src->buffer[1] = (JOCTET)M_EOI;
00241 src->pub.next_input_byte = src->buffer;
00242 src->pub.bytes_in_buffer = 2;
00243
00244 return TRUE;
00245 }
00246
00247
00248 METHODDEF(void) skip_input_data(j_decompress_ptr cinfo, long num_bytes)
00249 {
00250 mjpeg_src_ptr src = (mjpeg_src_ptr)cinfo->src;
00251
00252 src->pub.next_input_byte += (size_t)num_bytes;
00253 src->pub.bytes_in_buffer -= (size_t)num_bytes;
00254 }
00255
00256
00257 METHODDEF(void) term_source(j_decompress_ptr cinfo)
00258 {
00259 }
00260
00261 GLOBAL(void) jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long bytes)
00262 {
00263 mjpeg_src_ptr src;
00264
00265
00266 if(cinfo->src == NULL)
00267 {
00268 cinfo->src = (struct jpeg_source_mgr*)
00269 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
00270 JPOOL_PERMANENT,
00271 sizeof(mjpeg_source_mgr));
00272 src = (mjpeg_src_ptr)cinfo->src;
00273 }
00274
00275 src = (mjpeg_src_ptr)cinfo->src;
00276 src->pub.init_source = init_source;
00277 src->pub.fill_input_buffer = fill_input_buffer;
00278 src->pub.skip_input_data = skip_input_data;
00279 src->pub.resync_to_restart = jpeg_resync_to_restart;
00280 src->pub.term_source = term_source;
00281 src->pub.bytes_in_buffer = bytes;
00282 src->pub.next_input_byte = buffer;
00283 src->buffer = buffer;
00284 src->bytes = bytes;
00285 }
00286
00287
00288 static
00289 unsigned char jpeg_odml_dht[0x1a4] = {
00290 0xff, 0xc4, 0x01, 0xa2,
00291
00292 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00293 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
00294
00295 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
00296 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
00297
00298 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
00299 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
00300 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
00301 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
00302 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
00303 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
00304 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
00305 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
00306 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
00307 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
00308 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
00309 0xf9, 0xfa,
00310
00311 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
00312 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
00313 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
00314 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
00315 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
00316 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
00317 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
00318 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
00319 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
00320 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
00321 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
00322 0xf9, 0xfa
00323 };
00324
00325
00326
00327
00328
00329
00330 static
00331 int jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
00332 JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
00333 {
00334 unsigned int length = (dht[2] << 8) + dht[3] - 2;
00335 unsigned int pos = 4;
00336 unsigned int count, i;
00337 int index;
00338
00339 JHUFF_TBL **hufftbl;
00340 unsigned char bits[17];
00341 unsigned char huffval[256];
00342
00343 while (length > 16)
00344 {
00345 bits[0] = 0;
00346 index = dht[pos++];
00347 count = 0;
00348 for (i = 1; i <= 16; ++i)
00349 {
00350 bits[i] = dht[pos++];
00351 count += bits[i];
00352 }
00353 length -= 17;
00354
00355 if (count > 256 || count > length)
00356 return -1;
00357
00358 for (i = 0; i < count; ++i)
00359 huffval[i] = dht[pos++];
00360 length -= count;
00361
00362 if (index & 0x10)
00363 {
00364 index -= 0x10;
00365 hufftbl = &ac_tables[index];
00366 }
00367 else
00368 hufftbl = &dc_tables[index];
00369
00370 if (index < 0 || index >= NUM_HUFF_TBLS)
00371 return -1;
00372
00373 if (*hufftbl == NULL)
00374 *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
00375 if (*hufftbl == NULL)
00376 return -1;
00377
00378 memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
00379 memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
00380 }
00381
00382 if (length != 0)
00383 return -1;
00384
00385 return 0;
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 static void reset_buffer(unsigned char **buffer, long *size, long *allocated)
00403 {
00404 *size = 0;
00405 }
00406
00407 static void delete_buffer(unsigned char **buffer, long *size, long *allocated)
00408 {
00409 if(*buffer)
00410 {
00411 free(*buffer);
00412 *size = 0;
00413 *allocated = 0;
00414 }
00415 }
00416
00417 static void append_buffer(unsigned char **buffer,
00418 long *size,
00419 long *allocated,
00420 unsigned char *data,
00421 long data_size)
00422 {
00423 if(!*buffer)
00424 {
00425 *buffer = calloc(1, 65536);
00426 *size = 0;
00427 *allocated = 65536;
00428 }
00429
00430 if(*size + data_size + 0x100 > *allocated)
00431 {
00432 *allocated = *size + data_size + 0x100;
00433 *buffer = realloc(*buffer, *allocated);
00434 }
00435
00436 memcpy(*buffer + *size, data, data_size);
00437 *size += data_size;
00438 }
00439
00440 static void allocate_temps(mjpeg_t *mjpeg)
00441 {
00442 int i;
00443
00444 if(!mjpeg->temp_data)
00445 {
00446 switch(mjpeg->jpeg_color_model)
00447 {
00448 case BC_YUV422P:
00449 mjpeg->temp_data = calloc(1, mjpeg->coded_w * mjpeg->coded_h * 2);
00450 mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
00451 mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
00452 mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
00453 for(i = 0; i < mjpeg->coded_h; i++)
00454 {
00455 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
00456 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w / 2;
00457 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;
00458 }
00459 break;
00460
00461 case BC_YUV444P:
00462 mjpeg->temp_data = calloc(1, mjpeg->coded_w * mjpeg->coded_h * 3);
00463 mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
00464 mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
00465 mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
00466 if(mjpeg->greyscale)
00467 {
00468 memset(mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h,
00469 0x80,
00470 mjpeg->coded_w * mjpeg->coded_h * 2);
00471 }
00472 for(i = 0; i < mjpeg->coded_h; i++)
00473 {
00474 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
00475 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
00476 mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
00477 }
00478 break;
00479
00480 case BC_YUV420P:
00481 mjpeg->temp_data = calloc(1, mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h / 2);
00482 mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
00483 mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
00484 mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
00485 for(i = 0; i < mjpeg->coded_h; i++)
00486 {
00487 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
00488 if(i < mjpeg->coded_h / 2)
00489 {
00490 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * (mjpeg->coded_w / 2);
00491 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);
00492 }
00493 }
00494 break;
00495 }
00496 }
00497 }
00498
00499 static int get_input_row(mjpeg_t *mjpeg, mjpeg_compressor *compressor, int i)
00500 {
00501 int input_row;
00502 if(mjpeg->fields > 1)
00503 input_row = i * 2 + compressor->instance;
00504 else
00505 input_row = i;
00506 if(input_row >= mjpeg->coded_h) input_row = mjpeg->coded_h - 1;
00507 return input_row;
00508 }
00509
00510
00511 static void get_rows(mjpeg_t *mjpeg, mjpeg_compressor *compressor)
00512 {
00513 int i;
00514 switch(mjpeg->jpeg_color_model)
00515 {
00516 case BC_YUV444P:
00517 {
00518 if(!compressor->rows[0])
00519 {
00520 compressor->rows[0] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
00521 compressor->rows[1] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
00522 compressor->rows[2] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
00523 }
00524
00525
00526 if(mjpeg->color_model == BC_YUV444P &&
00527 mjpeg->output_w == mjpeg->coded_w &&
00528 mjpeg->output_h == mjpeg->coded_h)
00529 {
00530 for(i = 0; i < compressor->coded_field_h; i++)
00531 {
00532 int input_row = get_input_row(mjpeg, compressor, i);
00533 compressor->rows[0][i] = mjpeg->y_argument +
00534 mjpeg->coded_w * input_row;
00535 compressor->rows[1][i] = mjpeg->u_argument +
00536 mjpeg->coded_w * input_row;
00537 compressor->rows[2][i] = mjpeg->v_argument +
00538 mjpeg->coded_w * input_row;
00539 }
00540 }
00541 else
00542 {
00543 for(i = 0; i < compressor->coded_field_h; i++)
00544 {
00545 int input_row = get_input_row(mjpeg, compressor, i);
00546 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
00547 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
00548 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
00549 }
00550 }
00551 break;
00552 }
00553
00554 case BC_YUV422P:
00555 {
00556 if(!compressor->rows[0])
00557 {
00558 compressor->rows[0] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
00559 compressor->rows[1] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
00560 compressor->rows[2] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
00561 }
00562
00563
00564 if(mjpeg->color_model == BC_YUV422P &&
00565 mjpeg->output_w == mjpeg->coded_w &&
00566 mjpeg->output_h == mjpeg->coded_h)
00567 {
00568 for(i = 0; i < compressor->coded_field_h; i++)
00569 {
00570 int input_row = get_input_row(mjpeg, compressor, i);
00571 compressor->rows[0][i] = mjpeg->y_argument +
00572 mjpeg->coded_w * input_row;
00573 compressor->rows[1][i] = mjpeg->u_argument +
00574 (mjpeg->coded_w / 2) * input_row;
00575 compressor->rows[2][i] = mjpeg->v_argument +
00576 (mjpeg->coded_w / 2) * input_row;
00577 }
00578 }
00579 else
00580 {
00581 for(i = 0; i < compressor->coded_field_h; i++)
00582 {
00583 int input_row = get_input_row(mjpeg, compressor, i);
00584 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
00585 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
00586 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
00587 }
00588 }
00589 break;
00590 }
00591
00592 case BC_YUV420P:
00593 {
00594 if(!compressor->rows[0])
00595 {
00596 compressor->rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
00597 compressor->rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
00598 compressor->rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
00599 }
00600
00601
00602 if(mjpeg->color_model == BC_YUV420P &&
00603 mjpeg->output_w == mjpeg->coded_w &&
00604 mjpeg->output_h == mjpeg->coded_h)
00605 {
00606 for(i = 0; i < compressor->coded_field_h; i++)
00607 {
00608 int input_row = get_input_row(mjpeg, compressor, i);
00609 compressor->rows[0][i] = mjpeg->y_argument +
00610 mjpeg->coded_w * input_row;
00611 if(i < compressor->coded_field_h / 2)
00612 {
00613 compressor->rows[1][i] = mjpeg->u_argument +
00614 (mjpeg->coded_w / 2) * input_row;
00615 compressor->rows[2][i] = mjpeg->v_argument +
00616 (mjpeg->coded_w / 2) * input_row;
00617 }
00618 }
00619 }
00620 else
00621 {
00622 for(i = 0; i < compressor->coded_field_h; i++)
00623 {
00624 int input_row = get_input_row(mjpeg, compressor, i);
00625 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
00626 if(i < compressor->coded_field_h / 2)
00627 {
00628 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
00629 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
00630 }
00631 }
00632 }
00633 break;
00634 }
00635 }
00636 }
00637
00638 static void delete_rows(mjpeg_compressor *compressor)
00639 {
00640 if(compressor->rows[0])
00641 {
00642 free(compressor->rows[0]);
00643 free(compressor->rows[1]);
00644 free(compressor->rows[2]);
00645 }
00646 }
00647
00648
00649 static void new_jpeg_objects(mjpeg_compressor *engine)
00650 {
00651 engine->jpeg_decompress.err = jpeg_std_error(&(engine->jpeg_error.pub));
00652 engine->jpeg_error.pub.error_exit = mjpeg_error_exit;
00653
00654 jpeg_create_decompress(&(engine->jpeg_decompress));
00655 engine->jpeg_decompress.raw_data_out = TRUE;
00656 engine->jpeg_decompress.dct_method = JDCT_IFAST;
00657 }
00658
00659 static void delete_jpeg_objects(mjpeg_compressor *engine)
00660 {
00661 jpeg_destroy_decompress(&(engine->jpeg_decompress));
00662 }
00663
00664
00665
00666 static void unlock_compress_loop(mjpeg_compressor *engine)
00667 {
00668 pthread_mutex_unlock(&(engine->input_lock));
00669 }
00670
00671 static void lock_compress_loop(mjpeg_compressor *engine)
00672 {
00673 pthread_mutex_lock(&(engine->output_lock));
00674 }
00675
00676
00677 static void get_mcu_rows(mjpeg_t *mjpeg,
00678 mjpeg_compressor *engine,
00679 int start_row)
00680 {
00681 int i, j, scanline;
00682 for(i = 0; i < 3; i++)
00683 {
00684 for(j = 0; j < 16; j++)
00685 {
00686 if(i > 0 && j >= 8 && mjpeg->jpeg_color_model == BC_YUV420P) break;
00687
00688 scanline = start_row;
00689 if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) scanline /= 2;
00690 scanline += j;
00691 if(scanline >= engine->coded_field_h) scanline = engine->coded_field_h - 1;
00692 engine->mcu_rows[i][j] = engine->rows[i][scanline];
00693 }
00694 }
00695 }
00696
00697
00698 static void decompress_field(mjpeg_compressor *engine)
00699 {
00700 mjpeg_t *mjpeg = engine->mjpeg;
00701 long buffer_offset = engine->instance * mjpeg->input_field2;
00702 unsigned char *buffer = mjpeg->input_data + buffer_offset;
00703 long buffer_size;
00704 int i, j;
00705
00706
00707 if(engine->instance == 0 && mjpeg->fields > 1)
00708 buffer_size = mjpeg->input_field2 - buffer_offset;
00709 else
00710 buffer_size = mjpeg->input_size - buffer_offset;
00711
00712 mjpeg->error = 0;
00713
00714 if(setjmp(engine->jpeg_error.setjmp_buffer))
00715 {
00716
00717 delete_jpeg_objects(engine);
00718 new_jpeg_objects(engine);
00719 mjpeg->error = 1;
00720
00721 goto finish;
00722 }
00723
00724
00725 jpeg_buffer_src(&engine->jpeg_decompress,
00726 buffer,
00727 buffer_size);
00728 jpeg_read_header(&engine->jpeg_decompress, TRUE);
00729
00730 if ( engine->jpeg_decompress.ac_huff_tbl_ptrs[0] == NULL &&
00731 engine->jpeg_decompress.ac_huff_tbl_ptrs[1] == NULL &&
00732 engine->jpeg_decompress.dc_huff_tbl_ptrs[0] == NULL &&
00733 engine->jpeg_decompress.dc_huff_tbl_ptrs[1] == NULL )
00734 jpeg_load_dht( &engine->jpeg_decompress,
00735 jpeg_odml_dht,
00736 engine->jpeg_decompress.ac_huff_tbl_ptrs,
00737 engine->jpeg_decompress.dc_huff_tbl_ptrs );
00738
00739 engine->jpeg_decompress.raw_data_out = TRUE;
00740 jpeg_start_decompress(&engine->jpeg_decompress);
00741
00742
00743 if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
00744 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
00745 mjpeg->jpeg_color_model = BC_YUV420P;
00746 else
00747 if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 1 &&
00748 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
00749 mjpeg->jpeg_color_model = BC_YUV422P;
00750 else
00751 mjpeg->jpeg_color_model = BC_YUV444P;
00752
00753 if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE)
00754 mjpeg->greyscale = 1;
00755
00756
00757
00758 pthread_mutex_lock(&(mjpeg->decompress_init));
00759 allocate_temps(mjpeg);
00760 pthread_mutex_unlock(&(mjpeg->decompress_init));
00761 get_rows(mjpeg, engine);
00762
00763
00764 while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
00765 {
00766 get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
00767 jpeg_read_raw_data(&engine->jpeg_decompress,
00768 engine->mcu_rows,
00769 engine->coded_field_h);
00770 }
00771 jpeg_finish_decompress(&engine->jpeg_decompress);
00772
00773
00774 finish:
00775 ;
00776 }
00777
00778 void mjpeg_decompress_loop(mjpeg_compressor *engine)
00779 {
00780 while(!engine->done)
00781 {
00782 pthread_mutex_lock(&engine->input_lock);
00783 if(!engine->done)
00784 {
00785 decompress_field(engine);
00786 }
00787 pthread_mutex_unlock(&(engine->output_lock));
00788 }
00789 }
00790
00791
00792 static void compress_field(mjpeg_compressor *engine)
00793 {
00794 int i, j;
00795 mjpeg_t *mjpeg = engine->mjpeg;
00796
00797
00798 get_rows(engine->mjpeg, engine);
00799 reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
00800 jpeg_buffer_dest(&engine->jpeg_compress, engine);
00801
00802
00803 engine->jpeg_compress.raw_data_in = TRUE;
00804 jpeg_start_compress(&engine->jpeg_compress, TRUE);
00805
00806 while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
00807 {
00808 get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
00809
00810 jpeg_write_raw_data(&engine->jpeg_compress,
00811 engine->mcu_rows,
00812 engine->coded_field_h);
00813 }
00814 jpeg_finish_compress(&engine->jpeg_compress);
00815
00816 }
00817
00818
00819 void mjpeg_compress_loop(mjpeg_compressor *engine)
00820 {
00821 while(!engine->done)
00822 {
00823 pthread_mutex_lock(&engine->input_lock);
00824 if(!engine->done)
00825 {
00826 compress_field(engine);
00827 }
00828 pthread_mutex_unlock(&engine->output_lock);
00829 }
00830 }
00831
00832 static void delete_temps(mjpeg_t *mjpeg)
00833 {
00834 if(mjpeg->temp_data)
00835 {
00836 free(mjpeg->temp_data);
00837 free(mjpeg->temp_rows[0]);
00838 free(mjpeg->temp_rows[1]);
00839 free(mjpeg->temp_rows[2]);
00840 }
00841 }
00842
00843 mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
00844 {
00845 mjpeg_compressor *result = calloc(1, sizeof(mjpeg_compressor));
00846 pthread_attr_t attr;
00847 struct sched_param param;
00848 pthread_mutexattr_t mutex_attr;
00849 int i;
00850
00851 result->mjpeg = mjpeg;
00852 result->instance = instance;
00853 new_jpeg_objects(result);
00854 result->field_h = mjpeg->output_h / mjpeg->fields;
00855 result->coded_field_h = (result->field_h % 16) ?
00856 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
00857
00858 result->mcu_rows[0] = malloc(16 * sizeof(unsigned char*));
00859 result->mcu_rows[1] = malloc(16 * sizeof(unsigned char*));
00860 result->mcu_rows[2] = malloc(16 * sizeof(unsigned char*));
00861
00862 pthread_mutexattr_init(&mutex_attr);
00863
00864 pthread_mutex_init(&(result->input_lock), &mutex_attr);
00865 pthread_mutex_lock(&(result->input_lock));
00866 pthread_mutex_init(&(result->output_lock), &mutex_attr);
00867 pthread_mutex_lock(&(result->output_lock));
00868
00869 pthread_attr_init(&attr);
00870 pthread_create(&(result->tid), &attr, (void*)mjpeg_decompress_loop, result);
00871
00872 return result;
00873 }
00874
00875 void mjpeg_delete_decompressor(mjpeg_compressor *engine)
00876 {
00877 engine->done = 1;
00878 pthread_mutex_unlock(&(engine->input_lock));
00879 pthread_join(engine->tid, 0);
00880 pthread_mutex_destroy(&(engine->input_lock));
00881 pthread_mutex_destroy(&(engine->output_lock));
00882 jpeg_destroy_decompress(&(engine->jpeg_decompress));
00883 delete_rows(engine);
00884 free(engine->mcu_rows[0]);
00885 free(engine->mcu_rows[1]);
00886 free(engine->mcu_rows[2]);
00887 free(engine);
00888 }
00889
00890 mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
00891 {
00892 pthread_attr_t attr;
00893 struct sched_param param;
00894 pthread_mutexattr_t mutex_attr;
00895 mjpeg_compressor *result = calloc(1, sizeof(mjpeg_compressor));
00896
00897 result->field_h = mjpeg->output_h / mjpeg->fields;
00898 result->coded_field_h = (result->field_h % 16) ?
00899 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
00900 result->mjpeg = mjpeg;
00901 result->instance = instance;
00902 result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
00903 jpeg_create_compress(&(result->jpeg_compress));
00904 result->jpeg_compress.image_width = mjpeg->output_w;
00905 result->jpeg_compress.image_height = result->field_h;
00906 result->jpeg_compress.input_components = 3;
00907 result->jpeg_compress.in_color_space = JCS_RGB;
00908 jpeg_set_defaults(&(result->jpeg_compress));
00909 result->jpeg_compress.input_components = 3;
00910 result->jpeg_compress.in_color_space = JCS_RGB;
00911 jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
00912
00913 if(mjpeg->use_float)
00914 result->jpeg_compress.dct_method = JDCT_FLOAT;
00915 else
00916 result->jpeg_compress.dct_method = JDCT_IFAST;
00917
00918
00919
00920 switch(mjpeg->fields)
00921 {
00922 case 1:
00923 mjpeg->jpeg_color_model = BC_YUV420P;
00924 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
00925 result->jpeg_compress.comp_info[0].v_samp_factor = 2;
00926 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
00927 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
00928 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
00929 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
00930 break;
00931 case 2:
00932 mjpeg->jpeg_color_model = BC_YUV422P;
00933 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
00934 result->jpeg_compress.comp_info[0].v_samp_factor = 1;
00935 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
00936 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
00937 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
00938 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
00939 break;
00940 }
00941 allocate_temps(mjpeg);
00942
00943 result->mcu_rows[0] = malloc(16 * sizeof(unsigned char*));
00944 result->mcu_rows[1] = malloc(16 * sizeof(unsigned char*));
00945 result->mcu_rows[2] = malloc(16 * sizeof(unsigned char*));
00946
00947 pthread_mutexattr_init(&mutex_attr);
00948
00949 pthread_mutex_init(&(result->input_lock), &mutex_attr);
00950 pthread_mutex_lock(&(result->input_lock));
00951 pthread_mutex_init(&(result->output_lock), &mutex_attr);
00952 pthread_mutex_lock(&(result->output_lock));
00953
00954 pthread_attr_init(&attr);
00955 pthread_create(&(result->tid), &attr, (void*)mjpeg_compress_loop, result);
00956 return result;
00957 }
00958
00959
00960 void mjpeg_delete_compressor(mjpeg_compressor *engine)
00961 {
00962 engine->done = 1;
00963 pthread_mutex_unlock(&(engine->input_lock));
00964 pthread_join(engine->tid, 0);
00965 pthread_mutex_destroy(&(engine->input_lock));
00966 pthread_mutex_destroy(&(engine->output_lock));
00967 jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
00968 if(engine->output_buffer) free(engine->output_buffer);
00969 delete_rows(engine);
00970 free(engine->mcu_rows[0]);
00971 free(engine->mcu_rows[1]);
00972 free(engine->mcu_rows[2]);
00973 free(engine);
00974 }
00975
00976 unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
00977 {
00978 return mjpeg->output_data;
00979 }
00980
00981 long mjpeg_output_field2(mjpeg_t *mjpeg)
00982 {
00983 return mjpeg->output_field2;
00984 }
00985
00986 long mjpeg_output_size(mjpeg_t *mjpeg)
00987 {
00988 return mjpeg->output_size;
00989 }
00990
00991 long mjpeg_output_allocated(mjpeg_t *mjpeg)
00992 {
00993 return mjpeg->output_allocated;
00994 }
00995
00996 void mjpeg_set_output_size(mjpeg_t *mjpeg, long output_size)
00997 {
00998 mjpeg->output_size = output_size;
00999 }
01000
01001
01002 int mjpeg_compress(mjpeg_t *mjpeg,
01003 unsigned char **row_pointers,
01004 unsigned char *y_plane,
01005 unsigned char *u_plane,
01006 unsigned char *v_plane,
01007 int color_model,
01008 int cpus)
01009 {
01010 int i, result = 0;
01011 int corrected_fields = mjpeg->fields;
01012 mjpeg->color_model = color_model;
01013 mjpeg->cpus = cpus;
01014
01015
01016
01017 reset_buffer(&mjpeg->output_data,
01018 &mjpeg->output_size,
01019 &mjpeg->output_allocated);
01020
01021
01022 for(i = 0; i < mjpeg->fields; i++)
01023 {
01024 if(!mjpeg->compressors[i])
01025 {
01026 mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
01027 }
01028 }
01029
01030
01031 mjpeg->row_argument = row_pointers;
01032 mjpeg->y_argument = y_plane;
01033 mjpeg->u_argument = u_plane;
01034 mjpeg->v_argument = v_plane;
01035
01036
01037 if(mjpeg->color_model != mjpeg->jpeg_color_model ||
01038 mjpeg->output_w != mjpeg->coded_w ||
01039 mjpeg->output_h != mjpeg->coded_h)
01040 {
01041
01042
01043
01044
01045 cmodel_transfer(0,
01046 row_pointers,
01047 mjpeg->temp_rows[0][0],
01048 mjpeg->temp_rows[1][0],
01049 mjpeg->temp_rows[2][0],
01050 y_plane,
01051 u_plane,
01052 v_plane,
01053 0,
01054 0,
01055 mjpeg->output_w,
01056 mjpeg->output_h,
01057 0,
01058 0,
01059 mjpeg->output_w,
01060 mjpeg->output_h,
01061 mjpeg->color_model,
01062 mjpeg->jpeg_color_model,
01063 0,
01064 mjpeg->output_w,
01065 mjpeg->coded_w);
01066 }
01067
01068
01069 if(mjpeg->deinterlace) corrected_fields = 1;
01070 for(i = 0; i < corrected_fields && !result; i++)
01071 {
01072 unlock_compress_loop(mjpeg->compressors[i]);
01073
01074 if(mjpeg->cpus < 2 && i < corrected_fields - 1)
01075 {
01076 lock_compress_loop(mjpeg->compressors[i]);
01077 }
01078 }
01079
01080
01081 for(i = 0; i < corrected_fields && !result; i++)
01082 {
01083 if(mjpeg->cpus > 1 || i == corrected_fields - 1)
01084 {
01085 lock_compress_loop(mjpeg->compressors[i]);
01086 }
01087
01088 append_buffer(&mjpeg->output_data,
01089 &mjpeg->output_size,
01090 &mjpeg->output_allocated,
01091 mjpeg->compressors[i]->output_buffer,
01092 mjpeg->compressors[i]->output_size);
01093 if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
01094 }
01095
01096 if(corrected_fields < mjpeg->fields)
01097 {
01098 append_buffer(&mjpeg->output_data,
01099 &mjpeg->output_size,
01100 &mjpeg->output_allocated,
01101 mjpeg->compressors[0]->output_buffer,
01102 mjpeg->compressors[0]->output_size);
01103 }
01104
01105 return 0;
01106 }
01107
01108
01109
01110 int mjpeg_decompress(mjpeg_t *mjpeg,
01111 unsigned char *buffer,
01112 long buffer_len,
01113 long input_field2,
01114 unsigned char **row_pointers,
01115 unsigned char *y_plane,
01116 unsigned char *u_plane,
01117 unsigned char *v_plane,
01118 int color_model,
01119 int cpus)
01120 {
01121 int i, result = 0;
01122 int got_first_thread = 0;
01123
01124
01125 if(buffer_len == 0) return 1;
01126 if(input_field2 == 0 && mjpeg->fields > 1) return 1;
01127
01128
01129
01130 for(i = 0; i < mjpeg->fields; i++)
01131 {
01132 if(!mjpeg->decompressors[i])
01133 {
01134 mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
01135 }
01136 }
01137
01138
01139
01140 mjpeg->row_argument = row_pointers;
01141 mjpeg->y_argument = y_plane;
01142 mjpeg->u_argument = u_plane;
01143 mjpeg->v_argument = v_plane;
01144 mjpeg->input_data = buffer;
01145 mjpeg->input_size = buffer_len;
01146 mjpeg->input_field2 = input_field2;
01147 mjpeg->color_model = color_model;
01148 mjpeg->cpus = cpus;
01149
01150
01151
01152 for(i = 0; i < mjpeg->fields && !result; i++)
01153 {
01154 unlock_compress_loop(mjpeg->decompressors[i]);
01155
01156
01157
01158 if(mjpeg->cpus < 2 || !mjpeg->temp_data)
01159 {
01160 lock_compress_loop(mjpeg->decompressors[i]);
01161 if(i == 0) got_first_thread = 1;
01162 }
01163 }
01164
01165
01166
01167 for(i = 0; i < mjpeg->fields && !result; i++)
01168 {
01169 if(mjpeg->cpus > 1)
01170 {
01171 if(i > 0 || !got_first_thread)
01172 lock_compress_loop(mjpeg->decompressors[i]);
01173 }
01174 }
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186 if((mjpeg->jpeg_color_model != mjpeg->color_model ||
01187 mjpeg->coded_w != mjpeg->output_w ||
01188 mjpeg->coded_h != mjpeg->output_h)
01189 &&
01190 (mjpeg->temp_data ||
01191 !mjpeg->error))
01192 {
01193 unsigned char *y_in = mjpeg->temp_rows[0][0];
01194 unsigned char *u_in = mjpeg->temp_rows[1][0];
01195 unsigned char *v_in = mjpeg->temp_rows[2][0];
01196
01197
01198
01199
01200
01201
01202 cmodel_transfer(row_pointers,
01203 0,
01204 y_plane,
01205 u_plane,
01206 v_plane,
01207 y_in,
01208 u_in,
01209 v_in,
01210 0,
01211 0,
01212 mjpeg->output_w,
01213 mjpeg->output_h,
01214 0,
01215 0,
01216 mjpeg->output_w,
01217 mjpeg->output_h,
01218 mjpeg->jpeg_color_model,
01219 mjpeg->color_model,
01220 0,
01221 mjpeg->coded_w,
01222 mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
01223
01224 }
01225 return 0;
01226 }
01227
01228
01229 void mjpeg_set_deinterlace(mjpeg_t *mjpeg, int value)
01230 {
01231 mjpeg->deinterlace = value;
01232 }
01233
01234 void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
01235 {
01236 mjpeg->quality = quality;
01237 }
01238
01239 void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
01240 {
01241 mjpeg->use_float = use_float;
01242 }
01243
01244 void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
01245 {
01246 mjpeg->cpus = cpus;
01247 }
01248
01249 void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan)
01250 {
01251 mjpeg->rowspan = rowspan;
01252 }
01253
01254 int mjpeg_get_fields(mjpeg_t *mjpeg)
01255 {
01256 return mjpeg->fields;
01257 }
01258
01259
01260 mjpeg_t* mjpeg_new(int w,
01261 int h,
01262 int fields)
01263 {
01264 mjpeg_t *result = calloc(1, sizeof(mjpeg_t));
01265 pthread_mutexattr_t mutex_attr;
01266 int i;
01267
01268 result->output_w = w;
01269 result->output_h = h;
01270 result->fields = fields;
01271 result->color_model = BC_RGB888;
01272 result->cpus = 1;
01273 result->quality = 80;
01274 result->use_float = 0;
01275
01276 pthread_mutexattr_init(&mutex_attr);
01277
01278 pthread_mutex_init(&(result->decompress_init), &mutex_attr);
01279
01280
01281
01282
01283
01284 result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
01285
01286 if(fields == 1)
01287 result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
01288 else
01289 result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
01290
01291
01292
01293
01294 return result;
01295 }
01296
01297
01298
01299
01300 void mjpeg_delete(mjpeg_t *mjpeg)
01301 {
01302 int i;
01303
01304 for(i = 0; i < mjpeg->fields; i++)
01305 {
01306
01307 if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
01308
01309 if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
01310
01311 }
01312
01313 delete_temps(mjpeg);
01314
01315 delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
01316
01317 free(mjpeg);
01318
01319 }
01320
01321
01322
01323 static void insert_space(unsigned char **buffer,
01324 long *buffer_size,
01325 long *buffer_allocated,
01326 long space_start,
01327 long space_len)
01328 {
01329 int in, out;
01330
01331 if(*buffer_allocated - *buffer_size < space_len)
01332 {
01333 *buffer_allocated += space_len;
01334 *buffer = realloc(*buffer, *buffer_allocated);
01335 }
01336
01337
01338 for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
01339 in >= space_start;
01340 in--, out--)
01341 {
01342 (*buffer)[out] = (*buffer)[in];
01343 }
01344 *buffer_size += space_len;
01345 }
01346
01347
01348 static inline int nextbyte(unsigned char *data, long *offset, long length)
01349 {
01350 if(length - *offset < 1) return 0;
01351 *offset += 1;
01352 return (unsigned char)data[*offset - 1];
01353 }
01354
01355 static inline int read_int32(unsigned char *data, long *offset, long length)
01356 {
01357 if(length - *offset < 4)
01358 {
01359 *offset = length;
01360 return 0;
01361 }
01362 *offset += 4;
01363 return ((((unsigned int)data[*offset - 4]) << 24) |
01364 (((unsigned int)data[*offset - 3]) << 16) |
01365 (((unsigned int)data[*offset - 2]) << 8) |
01366 (((unsigned int)data[*offset - 1])));
01367 }
01368
01369 static inline int read_int16(unsigned char *data, long *offset, long length)
01370 {
01371 if(length - *offset < 2)
01372 {
01373 *offset = length;
01374 return 0;
01375 }
01376
01377 *offset += 2;
01378 return ((((unsigned int)data[*offset - 2]) << 8) |
01379 (((unsigned int)data[*offset - 1])));
01380 }
01381
01382 static inline unsigned char read_char(unsigned char *data, long *offset, long length)
01383 {
01384 if(length - *offset < 1)
01385 {
01386 *offset = length;
01387 return 0;
01388 }
01389
01390 *offset += 1;
01391 return (unsigned char)data[*offset - 1];
01392 }
01393
01394 static inline int next_int16(unsigned char *data, long *offset, long length)
01395 {
01396 if(length - *offset < 2)
01397 {
01398 return 0;
01399 }
01400
01401 return ((((unsigned int)data[*offset]) << 8) |
01402 (((unsigned int)data[*offset + 1])));
01403 }
01404
01405 static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
01406 {
01407 if(length - *offset < 4)
01408 {
01409 *offset = length;
01410 return;
01411 }
01412
01413
01414 data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
01415 data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
01416 data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
01417 data[(*offset)++] = (unsigned char)(value & 0xff);
01418 return;
01419 }
01420
01421 static inline void write_char(unsigned char *data, long *offset, long length, unsigned char value)
01422 {
01423 if(length - *offset < 1)
01424 {
01425 *offset = length;
01426 return;
01427 }
01428
01429 data[(*offset)++] = value;
01430 return;
01431 }
01432
01433 static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
01434 {
01435 int c, done = 0;
01436
01437 while(*offset < buffer_size - 1)
01438 {
01439 if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff)
01440 {
01441 (*offset) += 2;
01442 return buffer[*offset - 1];
01443 }
01444
01445 (*offset)++;
01446 }
01447
01448 return 0;
01449
01450 }
01451
01452
01453 static int find_marker(unsigned char *buffer,
01454 long *offset,
01455 long buffer_size,
01456 unsigned long marker_type)
01457 {
01458 long result = 0;
01459 long marker_len;
01460
01461 while(!result && *offset < buffer_size - 1)
01462 {
01463 int marker = next_marker(buffer, offset, buffer_size);
01464 if(marker == (marker_type & 0xff)) result = 1;
01465 }
01466
01467 return !result;
01468 }
01469
01470
01471 typedef struct
01472 {
01473 int field_size;
01474 int padded_field_size;
01475 int next_offset;
01476 int quant_offset;
01477 int huffman_offset;
01478 int image_offset;
01479 int scan_offset;
01480 int data_offset;
01481 } qt_hdr_t;
01482
01483 typedef struct
01484 {
01485 int field_number;
01486 int field_size;
01487 int unpadded_field_size;
01488 } avi_hdr_t;
01489
01490 #define LML_MARKER_SIZE 0x2c
01491 #define LML_MARKER_TAG 0xffe3
01492 void insert_lml33_markers(unsigned char **buffer,
01493 long *field2_offset,
01494 long *buffer_size,
01495 long *buffer_allocated)
01496 {
01497 long marker_offset = -1;
01498 int marker_exists;
01499
01500
01501
01502
01503
01504 if(marker_offset < 0)
01505 {
01506 marker_offset = 2;
01507 insert_space(buffer,
01508 buffer_size,
01509 buffer_allocated,
01510 2,
01511 LML_MARKER_SIZE);
01512 }
01513 }
01514
01515 static int qt_table_offsets(unsigned char *buffer,
01516 long buffer_size,
01517 qt_hdr_t *header)
01518 {
01519 int done = 0;
01520 long offset = 0;
01521 int marker = 0;
01522 int field = 0;
01523 int len;
01524 int result = 0;
01525
01526 bzero(header, sizeof(qt_hdr_t) * 2);
01527
01528
01529 for(field = 0; field < 2; field++)
01530 {
01531 done = 0;
01532
01533 while(!done)
01534 {
01535 marker = next_marker(buffer,
01536 &offset,
01537 buffer_size);
01538
01539 len = 0;
01540
01541 switch(marker)
01542 {
01543 case M_SOI:
01544
01545 if(field > 0)
01546 {
01547 header[0].next_offset =
01548 header[0].padded_field_size =
01549 offset - 2;
01550 }
01551 len = 0;
01552 break;
01553
01554 case M_APP1:
01555
01556 if(buffer[offset + 6] == 'm' &&
01557 buffer[offset + 7] == 'j' &&
01558 buffer[offset + 8] == 'p' &&
01559 buffer[offset + 9] == 'a')
01560 {
01561 result = 1;
01562 done = 1;
01563 }
01564 break;
01565
01566 case M_DQT:
01567 if(!header[field].quant_offset)
01568 {
01569 header[field].quant_offset = offset - 2;
01570 if(field > 0)
01571 header[field].quant_offset -= header[0].next_offset;
01572 }
01573 len = read_int16(buffer, &offset, buffer_size);
01574 len -= 2;
01575 break;
01576
01577 case M_DHT:
01578 if(!header[field].huffman_offset)
01579 {
01580 header[field].huffman_offset = offset - 2;
01581 if(field > 0)
01582 header[field].huffman_offset -= header[0].next_offset;
01583 }
01584 len = read_int16(buffer, &offset, buffer_size);
01585 len -= 2;
01586 break;
01587
01588 case M_SOF0:
01589 if(!header[field].image_offset)
01590 {
01591 header[field].image_offset = offset - 2;
01592 if(field > 0)
01593 header[field].image_offset -= header[0].next_offset;
01594 }
01595 len = read_int16(buffer, &offset, buffer_size);
01596 len -= 2;
01597 break;
01598
01599 case M_SOS:
01600 header[field].scan_offset = offset - 2;
01601 if(field > 0)
01602 header[field].scan_offset -= header[0].next_offset;
01603 len = read_int16(buffer, &offset, buffer_size);
01604 len -= 2;
01605 header[field].data_offset = offset + len;
01606 if(field > 0)
01607 header[field].data_offset -= header[0].next_offset;
01608 break;
01609
01610
01611 case M_EOI:
01612 if(field > 0)
01613 {
01614 header[field].field_size =
01615 header[field].padded_field_size =
01616 offset - header[0].next_offset;
01617 header[field].next_offset = 0;
01618 }
01619 else
01620 {
01621
01622
01623
01624
01625 }
01626
01627 done = 1;
01628 len = 0;
01629 break;
01630
01631 default:
01632
01633 len = 0;
01634
01635
01636 break;
01637 }
01638
01639 if(!done) offset += len;
01640 if(offset >= buffer_size) done = 1;
01641 }
01642
01643 }
01644
01645 return result;
01646 }
01647
01648 static void insert_quicktime_marker(unsigned char *buffer,
01649 long buffer_size,
01650 long offset,
01651 qt_hdr_t *header)
01652 {
01653 write_int32(buffer, &offset, buffer_size, 0xff000000 |
01654 ((unsigned long)M_APP1 << 16) |
01655 (QUICKTIME_MARKER_SIZE - 2));
01656 write_int32(buffer, &offset, buffer_size, 0);
01657 write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
01658 write_int32(buffer, &offset, buffer_size, header->field_size);
01659 write_int32(buffer, &offset, buffer_size, header->padded_field_size);
01660 write_int32(buffer, &offset, buffer_size, header->next_offset);
01661 write_int32(buffer, &offset, buffer_size, header->quant_offset);
01662 write_int32(buffer, &offset, buffer_size, header->huffman_offset);
01663 write_int32(buffer, &offset, buffer_size, header->image_offset);
01664 write_int32(buffer, &offset, buffer_size, header->scan_offset);
01665 write_int32(buffer, &offset, buffer_size, header->data_offset);
01666 }
01667
01668
01669 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
01670 long *buffer_size,
01671 long *buffer_allocated,
01672 int fields,
01673 long *field2_offset)
01674 {
01675 qt_hdr_t header[2];
01676 long offset = 0;
01677 int exists = 0;
01678 *field2_offset = -1;
01679
01680 if(fields < 2) return;
01681
01682
01683
01684 exists = qt_table_offsets(*buffer, *buffer_size, header);
01685
01686
01687 if(exists) return;
01688
01689
01690
01691
01692
01693
01694
01695
01696 header[0].field_size += QUICKTIME_MARKER_SIZE;
01697 header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
01698 header[0].next_offset += QUICKTIME_MARKER_SIZE;
01699 header[0].quant_offset += QUICKTIME_MARKER_SIZE;
01700 header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
01701 header[0].image_offset += QUICKTIME_MARKER_SIZE;
01702 header[0].scan_offset += QUICKTIME_MARKER_SIZE;
01703 header[0].data_offset += QUICKTIME_MARKER_SIZE;
01704 header[1].field_size += QUICKTIME_MARKER_SIZE;
01705 header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
01706 header[1].quant_offset += QUICKTIME_MARKER_SIZE;
01707 header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
01708 header[1].image_offset += QUICKTIME_MARKER_SIZE;
01709 header[1].scan_offset += QUICKTIME_MARKER_SIZE;
01710 header[1].data_offset += QUICKTIME_MARKER_SIZE;
01711 *field2_offset = header[0].next_offset;
01712
01713
01714
01715
01716 insert_space(buffer,
01717 buffer_size,
01718 buffer_allocated,
01719 2,
01720 QUICKTIME_MARKER_SIZE);
01721
01722 insert_quicktime_marker(*buffer,
01723 *buffer_size,
01724 2,
01725 &header[0]);
01726
01727 insert_space(buffer,
01728 buffer_size,
01729 buffer_allocated,
01730 header[0].next_offset + 2,
01731 QUICKTIME_MARKER_SIZE);
01732
01733 header[1].next_offset = 0;
01734 insert_quicktime_marker(*buffer,
01735 *buffer_size,
01736 header[0].next_offset + 2,
01737 &header[1]);
01738 }
01739
01740
01741 static int avi_table_offsets(unsigned char *buffer,
01742 long buffer_size,
01743 avi_hdr_t *header)
01744 {
01745 int field2 = mjpeg_get_field2(buffer, buffer_size);
01746
01747 header[0].field_number = 1;
01748 header[0].field_size = field2;
01749 header[0].unpadded_field_size = field2;
01750
01751 header[1].field_number = 2;
01752 header[1].field_size = buffer_size - field2;
01753 header[1].unpadded_field_size = buffer_size - field2;
01754 return 0;
01755 }
01756
01757 static void insert_avi_marker(unsigned char *buffer,
01758 long buffer_size,
01759 long offset,
01760 avi_hdr_t *header)
01761 {
01762 write_int32(buffer, &offset, buffer_size, 0xff000000 |
01763 ((unsigned long)M_APP0 << 16) |
01764 (AVI_MARKER_SIZE - 2));
01765 write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
01766
01767
01768
01769 write_char(buffer, &offset, buffer_size, header->field_number);
01770 write_char(buffer, &offset, buffer_size, 0);
01771 write_int32(buffer, &offset, buffer_size, header->field_size);
01772 write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
01773 }
01774
01775 void mjpeg_insert_avi_markers(unsigned char **buffer,
01776 long *buffer_size,
01777 long *buffer_allocated,
01778 int fields,
01779 long *field2_offset)
01780 {
01781 avi_hdr_t header[2];
01782 long offset = 0;
01783 *field2_offset = -1;
01784
01785
01786
01787 if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
01788 {
01789 if((*buffer)[offset + 2] == 'A' &&
01790 (*buffer)[offset + 3] == 'V' &&
01791 (*buffer)[offset + 4] == 'I' &&
01792 (*buffer)[offset + 5] == '1')
01793 return;
01794 }
01795
01796
01797 avi_table_offsets(*buffer, *buffer_size, header);
01798
01799 header[0].field_size += AVI_MARKER_SIZE;
01800 header[0].unpadded_field_size += AVI_MARKER_SIZE;
01801 header[1].field_size += AVI_MARKER_SIZE;
01802 header[1].unpadded_field_size += AVI_MARKER_SIZE;
01803 *field2_offset = header[0].field_size;
01804
01805
01806 insert_space(buffer,
01807 buffer_size,
01808 buffer_allocated,
01809 2,
01810 AVI_MARKER_SIZE);
01811 insert_avi_marker(*buffer,
01812 *buffer_size,
01813 2,
01814 &header[0]);
01815
01816 insert_space(buffer,
01817 buffer_size,
01818 buffer_allocated,
01819 *field2_offset + 2,
01820 AVI_MARKER_SIZE);
01821 insert_avi_marker(*buffer,
01822 *buffer_size,
01823 *field2_offset + 2,
01824 &header[1]);
01825
01826
01827
01828 }
01829
01830
01831 static void read_avi_markers(unsigned char *buffer,
01832 long buffer_size,
01833 avi_hdr_t *header)
01834 {
01835 long offset = 0;
01836 int marker_count = 0;
01837 int result = 0;
01838 int marker_size = 0;
01839 while(marker_count < 2 && offset < buffer_size && !result)
01840 {
01841 result = find_marker(buffer,
01842 &offset,
01843 buffer_size,
01844 M_APP0);
01845 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
01846
01847
01848 if(!result && marker_size >= 16)
01849 {
01850
01851 offset += 6;
01852
01853 header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
01854 read_char(buffer, &offset, buffer_size);
01855 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
01856 header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
01857 marker_count++;
01858 }
01859 }
01860 }
01861
01862
01863 static void read_quicktime_markers(unsigned char *buffer,
01864 long buffer_size,
01865 qt_hdr_t *header)
01866 {
01867 long offset = 0;
01868 int marker_count = 0;
01869 int result = 0;
01870
01871 while(marker_count < 2 && offset < buffer_size && !result)
01872 {
01873 result = find_marker(buffer,
01874 &offset,
01875 buffer_size,
01876 M_APP1);
01877
01878 if(!result)
01879 {
01880
01881 read_int16(buffer, &offset, buffer_size);
01882
01883 read_int32(buffer, &offset, buffer_size);
01884
01885 read_int32(buffer, &offset, buffer_size);
01886
01887 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
01888 header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
01889 header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
01890 header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
01891 header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
01892 header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
01893 header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
01894 header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
01895 marker_count++;
01896 }
01897 }
01898
01899 }
01900
01901 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
01902 {
01903 qt_hdr_t header[2];
01904 bzero(&header, sizeof(qt_hdr_t) * 2);
01905
01906 read_quicktime_markers(buffer, buffer_size, header);
01907 return header[0].next_offset;
01908 }
01909
01910 long mjpeg_get_avi_field2(unsigned char *buffer,
01911 long buffer_size,
01912 int *field_dominance)
01913 {
01914 avi_hdr_t header[2];
01915 bzero(&header, sizeof(avi_hdr_t) * 2);
01916 read_avi_markers(buffer, buffer_size, header);
01917
01918 *field_dominance = (header[0].field_number == 1) ? 1 : 2;
01919
01920
01921
01922 if(header[0].field_size)
01923 {
01924 return header[0].field_size;
01925 }
01926 else
01927 {
01928 return mjpeg_get_field2(buffer, buffer_size);
01929 }
01930 return 0;
01931 }
01932
01933 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
01934 {
01935 long result = 0;
01936 int total_fields = 0;
01937 long offset = 0;
01938 long field2_offset = 0;
01939 int i;
01940
01941 for(i = 0; i < buffer_size; i++)
01942 {
01943 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
01944 {
01945 total_fields++;
01946 field2_offset = i;
01947 if(total_fields == 2) break;
01948 }
01949 }
01950
01951
01952 return field2_offset;
01953 }
01954
01955 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
01956 {
01957 long offset = 0;
01958 find_marker(data,
01959 &offset,
01960 data_size,
01961 M_SOF0);
01962 *h = (data[offset + 3] << 8) | (data[offset + 4]);
01963 *w = (data[offset + 5] << 8) | (data[offset + 6]);
01964 }
01965
01966