home *** CD-ROM | disk | FTP | other *** search
/ Geek 6 / Geek-006.iso / linux / video / xmovie-1.5.3.tar.gz / xmovie-1.5.3.tar / xmovie-1.5.3 / quicktime / libmjpeg.c < prev    next >
C/C++ Source or Header  |  2000-11-29  |  36KB  |  1,398 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "colormodels.h"
  4. #include "libmjpeg.h"
  5.  
  6. /* JPEG MARKERS */
  7. #define   M_SOF0    0xc0
  8. #define   M_SOF1    0xc1
  9. #define   M_SOF2    0xc2
  10. #define   M_SOF3    0xc3
  11. #define   M_SOF5    0xc5
  12. #define   M_SOF6    0xc6
  13. #define   M_SOF7    0xc7
  14. #define   M_JPG     0xc8
  15. #define   M_SOF9    0xc9
  16. #define   M_SOF10   0xca
  17. #define   M_SOF11   0xcb
  18. #define   M_SOF13   0xcd
  19. #define   M_SOF14   0xce
  20. #define   M_SOF15   0xcf
  21. #define   M_DHT     0xc4
  22. #define   M_DAC     0xcc
  23. #define   M_RST0    0xd0
  24. #define   M_RST1    0xd1
  25. #define   M_RST2    0xd2
  26. #define   M_RST3    0xd3
  27. #define   M_RST4    0xd4
  28. #define   M_RST5    0xd5
  29. #define   M_RST6    0xd6
  30. #define   M_RST7    0xd7
  31. #define   M_SOI     0xd8
  32. #define   M_EOI     0xd9
  33. #define   M_SOS     0xda
  34. #define   M_DQT     0xdb
  35. #define   M_DNL     0xdc
  36. #define   M_DRI     0xdd
  37. #define   M_DHP     0xde
  38. #define   M_EXP     0xdf
  39. #define   M_APP0    0xe0
  40. #define   M_APP1    0xe1
  41. #define   M_APP2    0xe2
  42. #define   M_APP3    0xe3
  43. #define   M_APP4    0xe4
  44. #define   M_APP5    0xe5
  45. #define   M_APP6    0xe6
  46. #define   M_APP7    0xe7
  47. #define   M_APP8    0xe8
  48. #define   M_APP9    0xe9
  49. #define   M_APP10   0xea
  50. #define   M_APP11   0xeb
  51. #define   M_APP12   0xec
  52. #define   M_APP13   0xed
  53. #define   M_APP14   0xee
  54. #define   M_APP15   0xef
  55. #define   M_JPG0    0xf0
  56. #define   M_JPG13   0xfd
  57. #define   M_COM     0xfe
  58. #define   M_TEM     0x01
  59. #define   M_ERROR   0x100
  60.  
  61. #define QUICKTIME_MARKER_SIZE 0x2c
  62. #define QUICKTIME_JPEG_TAG 0x6d6a7067
  63.  
  64. METHODDEF(void) mjpeg_error_exit (j_common_ptr cinfo)
  65. {
  66. /* cinfo->err really points to a mjpeg_error_mgr struct, so coerce pointer */
  67.       mjpeg_error_ptr mjpegerr = (mjpeg_error_ptr) cinfo->err;
  68.  
  69. /* Always display the message. */
  70. /* We could postpone this until after returning, if we chose. */
  71.       (*cinfo->err->output_message) (cinfo);
  72.  
  73. /* Return control to the setjmp point */
  74.       longjmp(mjpegerr->setjmp_buffer, 1);
  75. }
  76.  
  77. typedef struct 
  78. {
  79.     struct jpeg_destination_mgr pub; /* public fields */
  80.  
  81.     JOCTET *buffer;        /* Pointer to buffer */
  82.     mjpeg_compressor *engine;
  83. } mjpeg_destination_mgr;
  84.  
  85. typedef mjpeg_destination_mgr *mjpeg_dest_ptr;
  86.  
  87.  
  88. /*
  89.  * Initialize destination --- called by jpeg_start_compress
  90.  * before any data is actually written.
  91.  */
  92.  
  93. METHODDEF(void) init_destination(j_compress_ptr cinfo)
  94. {
  95.       mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
  96.  
  97. /* Set the pointer to the preallocated buffer */
  98.     if(!dest->engine->output_buffer)
  99.     {
  100.         dest->engine->output_buffer = calloc(1, 65536);
  101.         dest->engine->output_allocated = 65536;
  102.     }
  103.       dest->buffer = dest->engine->output_buffer;
  104.       dest->pub.next_output_byte = dest->engine->output_buffer;
  105.       dest->pub.free_in_buffer = dest->engine->output_allocated;
  106. }
  107.  
  108. /*
  109.  * Empty the output buffer --- called whenever buffer fills up.
  110.  *
  111.  * In typical applications, this should write the entire output buffer
  112.  * (ignoring the current state of next_output_byte & free_in_buffer),
  113.  * reset the pointer & count to the start of the buffer, and return TRUE
  114.  * indicating that the buffer has been dumped.
  115.  *
  116.  * In applications that need to be able to suspend compression due to output
  117.  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
  118.  * In this situation, the compressor will return to its caller (possibly with
  119.  * an indication that it has not accepted all the supplied scanlines).  The
  120.  * application should resume compression after it has made more room in the
  121.  * output buffer.  Note that there are substantial restrictions on the use of
  122.  * suspension --- see the documentation.
  123.  *
  124.  * When suspending, the compressor will back up to a convenient restart point
  125.  * (typically the start of the current MCU). next_output_byte & free_in_buffer
  126.  * indicate where the restart point will be if the current call returns FALSE.
  127.  * Data beyond this point will be regenerated after resumption, so do not
  128.  * write it out when emptying the buffer externally.
  129.  */
  130.  
  131. METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
  132. {
  133. /* Allocate a bigger buffer. */
  134.     mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
  135.  
  136.     dest->engine->output_buffer = realloc(dest->engine->output_buffer, 
  137.         dest->engine->output_allocated * 2);
  138.     dest->engine->output_allocated *= 2;
  139.     dest->buffer = dest->engine->output_buffer;
  140.     dest->pub.next_output_byte = dest->buffer + dest->engine->output_size;
  141.     dest->pub.free_in_buffer = dest->engine->output_allocated - dest->engine->output_size;
  142.  
  143.     return TRUE;
  144. }
  145.  
  146. /*
  147.  * Terminate destination --- called by jpeg_finish_compress
  148.  * after all data has been written.  Usually needs to flush buffer.
  149.  *
  150.  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
  151.  * application must deal with any cleanup that should happen even
  152.  * for error exit.
  153.  */
  154. METHODDEF(void) term_destination(j_compress_ptr cinfo)
  155. {
  156. /* Just get the length */
  157.     mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
  158.     dest->engine->output_size = dest->engine->output_allocated - dest->pub.free_in_buffer;
  159. }
  160.  
  161. GLOBAL(void) jpeg_buffer_dest(j_compress_ptr cinfo, mjpeg_compressor *engine)
  162. {
  163.       mjpeg_dest_ptr dest;
  164.  
  165. /* The destination object is made permanent so that multiple JPEG images
  166.  * can be written to the same file without re-executing jpeg_stdio_dest.
  167.  * This makes it dangerous to use this manager and a different destination
  168.  * manager serially with the same JPEG object, because their private object
  169.  * sizes may be different.  Caveat programmer.
  170.  */
  171.     if(cinfo->dest == NULL) 
  172.     {    
  173. /* first time for this JPEG object? */
  174.           cinfo->dest = (struct jpeg_destination_mgr *)
  175.             (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, 
  176.                 JPOOL_PERMANENT,
  177.                 sizeof(mjpeg_destination_mgr));
  178.     }
  179.  
  180.     dest = (mjpeg_dest_ptr)cinfo->dest;
  181.     dest->pub.init_destination = init_destination;
  182.     dest->pub.empty_output_buffer = empty_output_buffer;
  183.     dest->pub.term_destination = term_destination;
  184.     dest->engine = engine;
  185. }
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. typedef struct {
  201.     struct jpeg_source_mgr pub;    /* public fields */
  202.  
  203.     JOCTET * buffer;        /* start of buffer */
  204.     int bytes;             /* total size of buffer */
  205. } mjpeg_source_mgr;
  206.  
  207. typedef mjpeg_source_mgr* mjpeg_src_ptr;
  208.  
  209. METHODDEF(void) init_source(j_decompress_ptr cinfo)
  210. {
  211.     mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
  212. }
  213.  
  214. METHODDEF(boolean) fill_input_buffer(j_decompress_ptr cinfo)
  215. {
  216.     mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
  217.  
  218.     src->buffer[0] = (JOCTET)0xFF;
  219.     src->buffer[1] = (JOCTET)M_EOI;
  220.     src->pub.next_input_byte = src->buffer;
  221.     src->pub.bytes_in_buffer = 2;
  222.  
  223.     return TRUE;
  224. }
  225.  
  226.  
  227. METHODDEF(void) skip_input_data(j_decompress_ptr cinfo, long num_bytes)
  228. {
  229.     mjpeg_src_ptr src = (mjpeg_src_ptr)cinfo->src;
  230.  
  231.     src->pub.next_input_byte += (size_t)num_bytes;
  232.     src->pub.bytes_in_buffer -= (size_t)num_bytes;
  233. }
  234.  
  235.  
  236. METHODDEF(void) term_source(j_decompress_ptr cinfo)
  237. {
  238. }
  239.  
  240. GLOBAL(void) jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long bytes)
  241. {
  242.     mjpeg_src_ptr src;
  243.  
  244. /* first time for this JPEG object? */
  245.     if(cinfo->src == NULL)
  246.     {    
  247.           cinfo->src = (struct jpeg_source_mgr*)
  248.             (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, 
  249.                     JPOOL_PERMANENT,
  250.                     sizeof(mjpeg_source_mgr));
  251.           src = (mjpeg_src_ptr)cinfo->src;
  252.     }
  253.  
  254.     src = (mjpeg_src_ptr)cinfo->src;
  255.     src->pub.init_source = init_source;
  256.     src->pub.fill_input_buffer = fill_input_buffer;
  257.     src->pub.skip_input_data = skip_input_data;
  258.     src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
  259.     src->pub.term_source = term_source;
  260.     src->pub.bytes_in_buffer = bytes;
  261.     src->pub.next_input_byte = buffer;
  262.     src->buffer = buffer;
  263.     src->bytes = bytes;
  264. }
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281. static void reset_buffer(unsigned char **buffer, long *size, long *allocated)
  282. {
  283.     *size = 0;
  284. }
  285.  
  286. static void delete_buffer(unsigned char **buffer, long *size, long *allocated)
  287. {
  288.     if(*buffer)
  289.     {
  290.         free(*buffer);
  291.         *size = 0;
  292.         *allocated = 0;
  293.     }
  294. }
  295.  
  296. static void append_buffer(unsigned char **buffer, 
  297.     long *size, 
  298.     long *allocated,
  299.     unsigned char *data,
  300.     long data_size)
  301. {
  302.     if(!*buffer)
  303.     {
  304.         *buffer = calloc(1, 65536);
  305.         *size = 0;
  306.         *allocated = 65536;
  307.     }
  308.  
  309.     if(*size + data_size > *allocated)
  310.     {
  311.         *allocated = *size + data_size;
  312.         *buffer = realloc(*buffer, *allocated);
  313.     }
  314.  
  315.     memcpy(*buffer + *size, data, data_size);
  316.     *size += data_size;
  317. }
  318.  
  319. static void allocate_temps(mjpeg_t *mjpeg)
  320. {
  321.     int i;
  322.  
  323.     if(!mjpeg->temp_data)
  324.     {
  325.         switch(mjpeg->jpeg_color_model)
  326.         {
  327.             case BC_YUV422P:
  328.                 mjpeg->temp_data = calloc(1, mjpeg->coded_w * mjpeg->coded_h * 2);
  329.                 mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
  330.                 mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
  331.                 mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
  332.                 for(i = 0; i < mjpeg->coded_h; i++)
  333.                 {
  334.                     mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
  335.                     mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w / 2;
  336.                     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;
  337.                 }
  338.                 break;
  339.  
  340.             case BC_YUV420P:
  341.                 mjpeg->temp_data = calloc(1, mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h / 2);
  342.                 mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
  343.                 mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
  344.                 mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
  345.                 for(i = 0; i < mjpeg->coded_h; i++)
  346.                 {
  347.                     mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
  348.                     if(i < mjpeg->coded_h / 2)
  349.                     {
  350.                         mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * (mjpeg->coded_w / 2);
  351.                         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);
  352.                     }
  353.                 }
  354.                 break;
  355.         }
  356.     }
  357. }
  358.  
  359. static int get_input_row(mjpeg_t *mjpeg, mjpeg_compressor *compressor, int i)
  360. {
  361.     int input_row;
  362.     if(mjpeg->fields > 1) 
  363.         input_row = i * 2 + compressor->instance;
  364.     else
  365.         input_row = i;
  366.     if(input_row >= mjpeg->coded_h) input_row = mjpeg->coded_h - 1;
  367.     return input_row;
  368. }
  369.  
  370. // Get pointers to rows for the JPEG compressor
  371. static void get_rows(mjpeg_t *mjpeg, mjpeg_compressor *compressor)
  372. {
  373.     int i;
  374.     if(mjpeg->jpeg_color_model == BC_YUV422P)
  375.     {
  376.         if(!compressor->rows[0])
  377.         {
  378.             compressor->rows[0] = calloc(1, sizeof(unsigned char*) * compressor->field_h);
  379.             compressor->rows[1] = calloc(1, sizeof(unsigned char*) * compressor->field_h);
  380.             compressor->rows[2] = calloc(1, sizeof(unsigned char*) * compressor->field_h);
  381.         }
  382.  
  383. // User colormodel matches jpeg colormodel
  384.         if(mjpeg->color_model == BC_YUV422P &&
  385.             mjpeg->output_w == mjpeg->coded_w &&
  386.             mjpeg->output_h == mjpeg->coded_h)
  387.         {
  388.             for(i = 0; i < compressor->field_h; i++)
  389.             {
  390.                 int input_row = get_input_row(mjpeg, compressor, i);
  391.                 compressor->rows[0][i] = mjpeg->y_argument + 
  392.                     mjpeg->coded_w * input_row;
  393.                 compressor->rows[1][i] = mjpeg->u_argument + 
  394.                     (mjpeg->coded_w / 2) * input_row;
  395.                 compressor->rows[2][i] = mjpeg->v_argument + 
  396.                     (mjpeg->coded_w / 2) * input_row;
  397.             }
  398.         }
  399.         else
  400.         {
  401.             for(i = 0; i < compressor->field_h; i++)
  402.             {
  403.                 int input_row = get_input_row(mjpeg, compressor, i);
  404.                 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
  405.                 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
  406.                 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
  407.             }
  408.         }
  409.     }
  410.     else
  411.     if(mjpeg->jpeg_color_model == BC_YUV420P)
  412.     {
  413.         if(!compressor->rows[0])
  414.         {
  415.             compressor->rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
  416.             compressor->rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
  417.             compressor->rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
  418.         }
  419.  
  420. // User colormodel matches jpeg colormodel
  421.         if(mjpeg->color_model == BC_YUV420P &&
  422.             mjpeg->output_w == mjpeg->coded_w &&
  423.             mjpeg->output_h == mjpeg->coded_h)
  424.         {
  425.             for(i = 0; i < compressor->field_h; i++)
  426.             {
  427.                 int input_row = get_input_row(mjpeg, compressor, i);
  428.                 compressor->rows[0][i] = mjpeg->y_argument + 
  429.                     mjpeg->coded_w * input_row;
  430.                 if(i < compressor->field_h / 2)
  431.                 {
  432.                     compressor->rows[1][i] = mjpeg->u_argument + 
  433.                         (mjpeg->coded_w / 2) * input_row;
  434.                     compressor->rows[2][i] = mjpeg->v_argument + 
  435.                         (mjpeg->coded_w / 2) * input_row;
  436.                 }
  437.             }
  438.         }
  439.         else
  440.         {
  441.             for(i = 0; i < compressor->field_h; i++)
  442.             {
  443.                 int input_row = get_input_row(mjpeg, compressor, i);
  444.                 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
  445.                 if(i < compressor->field_h / 2)
  446.                 {
  447.                     compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
  448.                     compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
  449.                 }
  450.             }
  451.         }
  452.     }
  453. }
  454.  
  455. static void delete_rows(mjpeg_compressor *compressor)
  456. {
  457.     if(compressor->rows[0])
  458.     {
  459.         free(compressor->rows[0]);
  460.         free(compressor->rows[1]);
  461.         free(compressor->rows[2]);
  462.     }
  463. }
  464.  
  465.  
  466. static void new_jpeg_objects(mjpeg_compressor *engine)
  467. {
  468.     engine->jpeg_decompress.err = jpeg_std_error(&(engine->jpeg_error.pub));
  469.     engine->jpeg_error.pub.error_exit = mjpeg_error_exit;
  470. /* Ideally the error handler would be set here but it must be called in a thread */
  471.     jpeg_create_decompress(&(engine->jpeg_decompress));
  472.     engine->jpeg_decompress.raw_data_out = TRUE;
  473. }
  474.  
  475. static void delete_jpeg_objects(mjpeg_compressor *engine)
  476. {
  477.     jpeg_destroy_decompress(&(engine->jpeg_decompress));
  478. }
  479.  
  480.  
  481.  
  482. static void unlock_compress_loop(mjpeg_compressor *engine)
  483. {
  484.     pthread_mutex_unlock(&(engine->input_lock));
  485. }
  486.  
  487. static void lock_compress_loop(mjpeg_compressor *engine)
  488. {
  489.     pthread_mutex_lock(&(engine->output_lock));
  490. }
  491.  
  492. // Make temp rows for compressor
  493. static void get_mcu_rows(mjpeg_t *mjpeg, 
  494.     mjpeg_compressor *engine,
  495.     int start_row)
  496. {
  497.     int i, j, scanline;
  498.     for(i = 0; i < 3; i++)
  499.     {
  500.         for(j = 0; j < 16; j++)
  501.         {
  502.             if(i > 0 && j >= 8 && mjpeg->jpeg_color_model == BC_YUV420P) break;
  503.  
  504.             scanline = start_row;
  505.             if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) scanline /= 2;
  506.             scanline += j;
  507.             if(scanline >= engine->field_h) scanline = engine->field_h - 1;
  508.             engine->mcu_rows[i][j] = engine->rows[i][scanline];
  509.         }
  510.     }
  511. }
  512.  
  513.  
  514. static void decompress_field(mjpeg_compressor *engine)
  515. {
  516.     mjpeg_t *mjpeg = engine->mjpeg;
  517.     long buffer_offset = engine->instance * mjpeg->input_field2;
  518.     unsigned char *buffer = mjpeg->input_data + buffer_offset;
  519.     long buffer_size;
  520.     int i, j;
  521.  
  522. //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
  523.     if(engine->instance == 0 && mjpeg->fields > 1)
  524.         buffer_size = mjpeg->input_field2 - buffer_offset;
  525.     else
  526.         buffer_size = mjpeg->input_size - buffer_offset;
  527.  
  528.  
  529.     if(setjmp(engine->jpeg_error.setjmp_buffer))
  530.     {
  531. /* If we get here, the JPEG code has signaled an error. */
  532.         delete_jpeg_objects(engine);
  533.         new_jpeg_objects(engine);
  534.         goto finish;
  535.     }
  536.  
  537.     jpeg_buffer_src(&engine->jpeg_decompress, 
  538.         buffer, 
  539.         buffer_size);
  540.     jpeg_read_header(&engine->jpeg_decompress, TRUE);
  541.  
  542. // Reset by jpeg_read_header
  543.     engine->jpeg_decompress.raw_data_out = TRUE;
  544.     jpeg_start_decompress(&engine->jpeg_decompress);
  545.  
  546. // Generate colormodel from jpeg sampling
  547.     if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 2)
  548.         mjpeg->jpeg_color_model = BC_YUV420P;
  549.     else
  550.         mjpeg->jpeg_color_model = BC_YUV422P;
  551.     allocate_temps(mjpeg);
  552.     get_rows(mjpeg, engine);
  553.  
  554. //printf("decompress_field 1\n");
  555.     while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
  556.     {
  557. //printf("decompress_field 2 %d\n", engine->jpeg_decompress.output_scanline);
  558.         get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
  559. //printf("decompress_field 3\n");
  560.  
  561.         jpeg_read_raw_data(&engine->jpeg_decompress, 
  562.             engine->mcu_rows, 
  563.             engine->field_h);
  564. //printf("decompress_field 4\n");
  565.     }
  566.     jpeg_finish_decompress(&engine->jpeg_decompress);
  567. //printf("decompress_field 5\n");
  568. finish:
  569. }
  570.  
  571. void mjpeg_decompress_loop(mjpeg_compressor *engine)
  572. {
  573.     while(!engine->done)
  574.     {
  575.         pthread_mutex_lock(&engine->input_lock);
  576.         if(!engine->done)
  577.         {
  578.             decompress_field(engine);
  579.         }
  580.         pthread_mutex_unlock(&(engine->output_lock));
  581.     }
  582. }
  583.  
  584.  
  585. static void compress_field(mjpeg_compressor *engine)
  586. {
  587.     int i, j;
  588.     mjpeg_t *mjpeg = engine->mjpeg;
  589.  
  590.     get_rows(engine->mjpeg, engine);
  591.     reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
  592.     jpeg_buffer_dest(&engine->jpeg_compress, engine);
  593.  
  594.  
  595.     engine->jpeg_compress.raw_data_in = TRUE;
  596.     jpeg_start_compress(&engine->jpeg_compress, TRUE);
  597.  
  598.     while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
  599.     {
  600.         get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
  601.  
  602.         jpeg_write_raw_data(&engine->jpeg_compress, 
  603.             engine->mcu_rows, 
  604.             engine->field_h);
  605.     }
  606.     jpeg_finish_compress(&engine->jpeg_compress);
  607. }
  608.  
  609.  
  610. void mjpeg_compress_loop(mjpeg_compressor *engine)
  611. {
  612.     while(!engine->done)
  613.     {
  614.         pthread_mutex_lock(&engine->input_lock);
  615.         if(!engine->done)
  616.         {
  617.             compress_field(engine);
  618.         }
  619.         pthread_mutex_unlock(&engine->output_lock);
  620.     }
  621. }
  622.  
  623. static void delete_temps(mjpeg_t *mjpeg)
  624. {
  625.     if(mjpeg->temp_data)
  626.     {
  627.         free(mjpeg->temp_data);
  628.         free(mjpeg->temp_rows[0]);
  629.         free(mjpeg->temp_rows[1]);
  630.         free(mjpeg->temp_rows[2]);
  631.     }
  632. }
  633.  
  634. mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
  635. {
  636.     mjpeg_compressor *result = calloc(1, sizeof(mjpeg_compressor));
  637.     pthread_attr_t  attr;
  638.     struct sched_param param;
  639.     pthread_mutexattr_t mutex_attr;
  640.     int i;
  641.  
  642.     result->mjpeg = mjpeg;
  643.     result->instance = instance;
  644.     new_jpeg_objects(result);
  645.     result->field_h = mjpeg->coded_h / mjpeg->fields;
  646.  
  647.     result->mcu_rows[0] = malloc(16 * sizeof(unsigned char*));
  648.     result->mcu_rows[1] = malloc(16 * sizeof(unsigned char*));
  649.     result->mcu_rows[2] = malloc(16 * sizeof(unsigned char*));
  650.  
  651.     pthread_mutexattr_init(&mutex_attr);
  652.     pthread_mutex_init(&(result->input_lock), &mutex_attr);
  653.     pthread_mutex_lock(&(result->input_lock));
  654.     pthread_mutex_init(&(result->output_lock), &mutex_attr);
  655.     pthread_mutex_lock(&(result->output_lock));
  656.  
  657.     pthread_attr_init(&attr);
  658.     pthread_create(&(result->tid), &attr, (void*)mjpeg_decompress_loop, result);
  659.  
  660.     return result;
  661. }
  662.  
  663. void mjpeg_delete_decompressor(mjpeg_compressor *engine)
  664. {
  665.     engine->done = 1;
  666.     pthread_mutex_unlock(&(engine->input_lock));
  667.     pthread_join(engine->tid, 0);
  668.     pthread_mutex_destroy(&(engine->input_lock));
  669.     pthread_mutex_destroy(&(engine->output_lock));
  670.     jpeg_destroy_decompress(&(engine->jpeg_decompress));
  671.     delete_rows(engine);
  672.     free(engine->mcu_rows[0]);
  673.     free(engine->mcu_rows[1]);
  674.     free(engine->mcu_rows[2]);
  675.     free(engine);
  676. }
  677.  
  678. mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
  679. {
  680.     pthread_attr_t  attr;
  681.     struct sched_param param;
  682.     pthread_mutexattr_t mutex_attr;
  683.     mjpeg_compressor *result = calloc(1, sizeof(mjpeg_compressor));
  684.  
  685.     result->field_h = mjpeg->coded_h / mjpeg->fields;
  686.     result->mjpeg = mjpeg;
  687.     result->instance = instance;
  688.     result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
  689.     jpeg_create_compress(&(result->jpeg_compress));
  690.     result->jpeg_compress.image_width = mjpeg->coded_w;
  691.     result->jpeg_compress.image_height = result->field_h;
  692.     result->jpeg_compress.input_components = 3;
  693.     result->jpeg_compress.in_color_space = JCS_RGB;
  694.     jpeg_set_defaults(&(result->jpeg_compress));
  695.     result->jpeg_compress.input_components = 3;
  696.     result->jpeg_compress.in_color_space = JCS_RGB;
  697.     jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
  698.     if(mjpeg->use_float) result->jpeg_compress.dct_method = JDCT_FLOAT;
  699.  
  700. /* Fix sampling */
  701.     switch(mjpeg->fields)
  702.     {
  703.         case 1:
  704.             mjpeg->jpeg_color_model = BC_YUV420P;
  705.             result->jpeg_compress.comp_info[0].h_samp_factor = 2;
  706.             result->jpeg_compress.comp_info[0].v_samp_factor = 2;
  707.             result->jpeg_compress.comp_info[1].h_samp_factor = 1;
  708.             result->jpeg_compress.comp_info[1].v_samp_factor = 1;
  709.             result->jpeg_compress.comp_info[2].h_samp_factor = 1;
  710.             result->jpeg_compress.comp_info[2].v_samp_factor = 1;
  711.             break;
  712.         case 2:
  713.             mjpeg->jpeg_color_model = BC_YUV422P;
  714.             result->jpeg_compress.comp_info[0].h_samp_factor = 2;
  715.             result->jpeg_compress.comp_info[0].v_samp_factor = 1;
  716.             result->jpeg_compress.comp_info[1].h_samp_factor = 1;
  717.             result->jpeg_compress.comp_info[1].v_samp_factor = 1;
  718.             result->jpeg_compress.comp_info[2].h_samp_factor = 1;
  719.             result->jpeg_compress.comp_info[2].v_samp_factor = 1;
  720.             break;
  721.     }
  722.     allocate_temps(mjpeg);
  723.  
  724.     result->mcu_rows[0] = malloc(16 * sizeof(unsigned char*));
  725.     result->mcu_rows[1] = malloc(16 * sizeof(unsigned char*));
  726.     result->mcu_rows[2] = malloc(16 * sizeof(unsigned char*));
  727.  
  728.     pthread_mutexattr_init(&mutex_attr);
  729.     pthread_mutex_init(&(result->input_lock), &mutex_attr);
  730.     pthread_mutex_lock(&(result->input_lock));
  731.     pthread_mutex_init(&(result->output_lock), &mutex_attr);
  732.     pthread_mutex_lock(&(result->output_lock));
  733.  
  734.     pthread_attr_init(&attr);
  735.     pthread_create(&(result->tid), &attr, (void*)mjpeg_compress_loop, result);
  736.     return result;
  737. }
  738.  
  739.  
  740. void mjpeg_delete_compressor(mjpeg_compressor *engine)
  741. {
  742.     engine->done = 1;
  743.     pthread_mutex_unlock(&(engine->input_lock));
  744.     pthread_join(engine->tid, 0);
  745.     pthread_mutex_destroy(&(engine->input_lock));
  746.     pthread_mutex_destroy(&(engine->output_lock));
  747.     jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
  748.     if(engine->output_buffer) free(engine->output_buffer);
  749.     delete_rows(engine);
  750.     free(engine->mcu_rows[0]);
  751.     free(engine->mcu_rows[1]);
  752.     free(engine->mcu_rows[2]);
  753.     free(engine);
  754. }
  755.  
  756. unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
  757. {
  758.     return mjpeg->output_data;
  759. }
  760.  
  761. long mjpeg_output_field2(mjpeg_t *mjpeg)
  762. {
  763.     return mjpeg->output_field2;
  764. }
  765.  
  766. long mjpeg_output_size(mjpeg_t *mjpeg)
  767. {
  768.     return mjpeg->output_size;
  769. }
  770.  
  771. int mjpeg_compress(mjpeg_t *mjpeg, 
  772.     unsigned char **row_pointers, 
  773.     unsigned char *y_plane, 
  774.     unsigned char *u_plane, 
  775.     unsigned char *v_plane,
  776.     int color_model,
  777.     int cpus)
  778. {
  779.     int i, result = 0;
  780.     mjpeg->color_model = color_model;
  781.     mjpeg->cpus = cpus;
  782.  
  783. /* Reset output buffer */
  784.     reset_buffer(&mjpeg->output_data, 
  785.         &mjpeg->output_size, 
  786.         &mjpeg->output_allocated);
  787.  
  788. /* Create compression engines as needed */
  789.     for(i = 0; i < mjpeg->fields; i++)
  790.     {
  791.         if(!mjpeg->compressors[i])
  792.         {
  793.             mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
  794.         }
  795.     }
  796.  
  797. /* Arm YUV buffers */
  798.     mjpeg->row_argument = row_pointers;
  799.     mjpeg->y_argument = y_plane;
  800.     mjpeg->u_argument = u_plane;
  801.     mjpeg->v_argument = v_plane;
  802. // User colormodel doesn't match encoder colormodel
  803. // Copy to interlacing buffer first
  804.     if(mjpeg->color_model != mjpeg->jpeg_color_model || 
  805.         mjpeg->output_w != mjpeg->coded_w ||
  806.         mjpeg->output_h != mjpeg->coded_h)
  807.     {
  808. //printf("libmjpeg %d %d\n", mjpeg->jpeg_color_model, mjpeg->color_model);
  809.         cmodel_transfer(0, 
  810.             row_pointers,
  811.             mjpeg->temp_rows[0][0],
  812.             mjpeg->temp_rows[1][0],
  813.             mjpeg->temp_rows[2][0],
  814.             y_plane,
  815.             u_plane,
  816.             v_plane,
  817.             0, 
  818.             0, 
  819.             mjpeg->output_w, 
  820.             mjpeg->output_h,
  821.             0, 
  822.             0, 
  823.             mjpeg->output_w, 
  824.             mjpeg->output_h,
  825.             mjpeg->color_model, 
  826.             mjpeg->jpeg_color_model,
  827.             0,
  828.             mjpeg->output_w);
  829.     }
  830.  
  831. /* Start the compressors on the image fields */
  832.     for(i = 0; i < mjpeg->fields && !result; i++)
  833.     {
  834.         unlock_compress_loop(mjpeg->compressors[i]);
  835.  
  836.         if(mjpeg->cpus < 2 && i < mjpeg->fields - 1)
  837.         {
  838.             lock_compress_loop(mjpeg->compressors[i]);
  839.         }
  840.     }
  841.  
  842. /* Wait for the compressors and store in master output */
  843.     for(i = 0; i < mjpeg->fields && !result; i++)
  844.     {
  845.         if(mjpeg->cpus > 1 || i == mjpeg->fields - 1)
  846.         {
  847.             lock_compress_loop(mjpeg->compressors[i]);
  848.         }
  849.  
  850.         append_buffer(&mjpeg->output_data, 
  851.             &mjpeg->output_size, 
  852.             &mjpeg->output_allocated,
  853.             mjpeg->compressors[i]->output_buffer, 
  854.             mjpeg->compressors[i]->output_size);
  855.         if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
  856.     }
  857.  
  858.     return 0;
  859. }
  860.  
  861.  
  862.  
  863. int mjpeg_decompress(mjpeg_t *mjpeg, 
  864.     unsigned char *buffer, 
  865.     long buffer_len,
  866.     long input_field2,  
  867.     unsigned char **row_pointers, 
  868.     unsigned char *y_plane, 
  869.     unsigned char *u_plane, 
  870.     unsigned char *v_plane,
  871.     int color_model,
  872.     int cpus)
  873. {
  874.     int i, result = 0;
  875.  
  876.     if(buffer_len == 0) return 1;
  877.     if(input_field2 == 0) return 1;
  878.  
  879. /* Create decompression engines as needed */
  880.     for(i = 0; i < mjpeg->fields; i++)
  881.     {
  882.         if(!mjpeg->decompressors[i])
  883.         {
  884.             mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
  885.         }
  886.     }
  887.  
  888. /* Arm YUV buffers */
  889.     mjpeg->row_argument = row_pointers;
  890.     mjpeg->y_argument = y_plane;
  891.     mjpeg->u_argument = u_plane;
  892.     mjpeg->v_argument = v_plane;
  893.     mjpeg->input_data = buffer;
  894.     mjpeg->input_size = buffer_len;
  895.     mjpeg->input_field2 = input_field2;
  896.     mjpeg->color_model = color_model;
  897.     mjpeg->cpus = cpus;
  898.  
  899. /* Start decompressors */
  900.     for(i = 0; i < mjpeg->fields && !result; i++)
  901.     {
  902.         unlock_compress_loop(mjpeg->decompressors[i]);
  903.  
  904. // Don't want second thread to start until temp data is allocated by the first        
  905.         if(mjpeg->cpus < 2 && i < mjpeg->fields - 1 && !mjpeg->temp_data)
  906.         {
  907.             lock_compress_loop(mjpeg->decompressors[i]);
  908.         }
  909.     }
  910.  
  911. /* Wait for decompressors */
  912.     for(i = 0; i < mjpeg->fields && !result; i++)
  913.     {
  914.         if(mjpeg->cpus > 1 || i == mjpeg->fields - 1)
  915.         {
  916.             lock_compress_loop(mjpeg->decompressors[i]);
  917.         }
  918.     }
  919.  
  920. //printf("%d %d\n", mjpeg->jpeg_color_model, mjpeg->color_model);
  921. /* Convert colormodel */
  922. // User colormodel didn't match decompressor
  923.     if(mjpeg->jpeg_color_model != mjpeg->color_model ||
  924.         mjpeg->coded_w != mjpeg->output_w ||
  925.         mjpeg->coded_h != mjpeg->output_h)
  926.     {
  927.         cmodel_transfer(row_pointers, 
  928.             0,
  929.             y_plane,
  930.             u_plane,
  931.             v_plane,
  932.             mjpeg->temp_rows[0][0],
  933.             mjpeg->temp_rows[1][0],
  934.             mjpeg->temp_rows[2][0],
  935.             0, 
  936.             0, 
  937.             mjpeg->output_w, 
  938.             mjpeg->output_h,
  939.             0, 
  940.             0, 
  941.             mjpeg->output_w, 
  942.             mjpeg->output_h,
  943.             mjpeg->jpeg_color_model,
  944.             mjpeg->color_model, 
  945.             0,
  946.             mjpeg->coded_w);
  947.     }
  948.     return 0;
  949. }
  950.  
  951.  
  952. void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
  953. {
  954.     mjpeg->quality = quality;
  955. }
  956.  
  957. void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
  958. {
  959.     mjpeg->use_float = use_float;
  960. }
  961.  
  962. void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
  963. {
  964.     mjpeg->cpus = cpus;
  965. }
  966.  
  967. int mjpeg_get_fields(mjpeg_t *mjpeg)
  968. {
  969.     return mjpeg->fields;
  970. }
  971.  
  972.  
  973. mjpeg_t* mjpeg_new(int w, 
  974.     int h, 
  975.     int fields)
  976. {
  977.     mjpeg_t *result = calloc(1, sizeof(mjpeg_t));
  978.     int i;
  979.  
  980.     result->output_w = w;
  981.     result->output_h = h;
  982.     result->fields = fields;
  983.     result->color_model = BC_RGB888;
  984.     result->cpus = 1;
  985.     result->quality = 100;
  986.     result->use_float = 0;
  987. // Calculate coded dimensions
  988. // An interlaced frame with 4:2:0 sampling must be a multiple of 32
  989.     result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
  990.     if(fields == 1)
  991.         result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
  992.     else
  993.         result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
  994. //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
  995.     return result;
  996. }
  997.  
  998.  
  999.  
  1000.  
  1001. void mjpeg_delete(mjpeg_t *mjpeg)
  1002. {
  1003.     int i;
  1004. //printf("mjpeg_delete 1\n");
  1005.     for(i = 0; i < mjpeg->fields; i++)
  1006.     {
  1007. //printf("mjpeg_delete 2\n");
  1008.         if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
  1009. //printf("mjpeg_delete 3\n");
  1010.         if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
  1011. //printf("mjpeg_delete 4\n");
  1012.     }
  1013. //printf("mjpeg_delete 5\n");
  1014.     delete_temps(mjpeg);
  1015. //printf("mjpeg_delete 6\n");
  1016.     delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
  1017. //printf("mjpeg_delete 7\n");
  1018.     free(mjpeg);
  1019. //printf("mjpeg_delete 2\n");
  1020. }
  1021.  
  1022.  
  1023. /* Open up a space to insert a marker */
  1024. static void insert_space(unsigned char **buffer, 
  1025.     long *buffer_size, 
  1026.     long *buffer_allocated,
  1027.     long space_start,
  1028.     long space_len)
  1029. {
  1030.     int in, out;
  1031. // Make sure enough space is available
  1032.     if(*buffer_allocated - *buffer_size < space_len)
  1033.     {
  1034.         *buffer_allocated += space_len;
  1035.         *buffer = realloc(*buffer, *buffer_allocated);
  1036.     }
  1037.  
  1038. // Shift data back
  1039.     for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
  1040.         in >= space_start;
  1041.         in--, out--)
  1042.     {
  1043.         (*buffer)[out] = (*buffer)[in];
  1044.     }
  1045.     *buffer_size += space_len;
  1046. }
  1047.  
  1048.  
  1049. static inline int nextbyte(unsigned char *data, long *offset, long length)
  1050. {
  1051.     if(length - *offset < 1) return 0;
  1052.     *offset += 1;
  1053.     return (unsigned char)data[*offset - 1];
  1054. }
  1055.  
  1056. static inline int next_int32(unsigned char *data, long *offset, long length)
  1057. {
  1058.     if(length - *offset < 4)
  1059.     {
  1060.         *offset = length;
  1061.         return 0;
  1062.     }
  1063.     *offset += 4;
  1064.     return ((((unsigned int)data[*offset - 4]) << 24) | 
  1065.         (((unsigned int)data[*offset - 3]) << 16) | 
  1066.         (((unsigned int)data[*offset - 2]) << 8) | 
  1067.         (((unsigned int)data[*offset - 1])));
  1068. }
  1069.  
  1070. static inline int next_int16(unsigned char *data, long *offset, long length)
  1071. {
  1072.     if(length - *offset < 2)    
  1073.     {
  1074.         *offset = length;
  1075.         return 0;
  1076.     }
  1077.  
  1078.     *offset += 2;
  1079.     return ((((unsigned int)data[*offset - 2]) << 8) | 
  1080.         (((unsigned int)data[*offset - 1])));
  1081. }
  1082.  
  1083. static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
  1084. {
  1085.     if(length - *offset < 4)
  1086.     {
  1087.         *offset = length;
  1088.         return;
  1089.     }
  1090.  
  1091.  
  1092.     data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
  1093.     data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
  1094.     data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
  1095.     data[(*offset)++] = (unsigned char)(value & 0xff);
  1096.     return;
  1097. }
  1098.  
  1099. static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
  1100. {
  1101.     int c, done = 0;  /* 1 - completion    2 - error */
  1102.  
  1103.     while(!done && *offset < buffer_size)
  1104.     {
  1105.         c = nextbyte(buffer, offset, buffer_size);
  1106. /* look for FF */
  1107.         while(*offset < buffer_size && !done && c != 0xFF)
  1108.         {
  1109.             if(!*buffer) done = 2;
  1110.             c = nextbyte(buffer, offset, buffer_size);
  1111.         }
  1112.  
  1113. /* now we've got 1 0xFF, keep reading until not 0xFF */
  1114.         do
  1115.         {
  1116.             if(*offset >= buffer_size) done = 2;
  1117.             c = nextbyte(buffer, offset, buffer_size);
  1118.         }while(*offset < buffer_size && !done && c == 0xFF);
  1119.  
  1120. /* not a 00 or FF */
  1121.         if (c != 0) done = 1; 
  1122.     }
  1123.  
  1124.     if(done == 1) 
  1125.         return c;
  1126.     else
  1127.         return 0;
  1128. }
  1129.  
  1130. /* Find the next marker after offset and return 0 on success */
  1131. static int find_marker(unsigned char *buffer, 
  1132.     long *offset, 
  1133.     long buffer_size,
  1134.     unsigned long marker_type)
  1135. {
  1136.     long result = 0;
  1137.     long marker_len;
  1138.  
  1139.     while(!result && *offset < buffer_size)
  1140.     {
  1141.         int marker = next_marker(buffer, offset, buffer_size);
  1142.         if(marker == (marker_type & 0xff)) result = 1;
  1143.     }
  1144.  
  1145.     return !result;
  1146. }
  1147.  
  1148.  
  1149. typedef struct
  1150. {
  1151.     int field_size;
  1152.     int padded_field_size;
  1153.     int next_offset;
  1154.     int quant_offset;
  1155.     int huffman_offset;
  1156.     int image_offset;
  1157.     int scan_offset;
  1158.     int data_offset;
  1159. } mjpeg_qt_hdr;
  1160.  
  1161. #define LML_MARKER_SIZE 0x2c
  1162. #define LML_MARKER_TAG 0xffe3
  1163. void insert_lml33_markers(unsigned char **buffer, 
  1164.     long *field2_offset, 
  1165.     long *buffer_size, 
  1166.     long *buffer_allocated)
  1167. {
  1168.     long marker_offset = -1;
  1169.     int marker_exists;
  1170.  
  1171. /* Search for existing marker to replace */
  1172. //    marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);
  1173.  
  1174. /* Insert new marker */
  1175.     if(marker_offset < 0)
  1176.     {
  1177.         marker_offset = 2;
  1178.         insert_space(buffer, 
  1179.             buffer_size, 
  1180.             buffer_allocated,
  1181.             2,
  1182.             LML_MARKER_SIZE);
  1183.     }
  1184. }
  1185.  
  1186. static void table_offsets(unsigned char *buffer, 
  1187.     long buffer_size, 
  1188.     mjpeg_qt_hdr *header)
  1189. {
  1190.     int done = 0;
  1191.     long offset = 0;
  1192.     int marker = 0;
  1193.     int field = 0;
  1194.     int len;
  1195.  
  1196.     bzero(header, sizeof(mjpeg_qt_hdr) * 2);
  1197.  
  1198. // Read every marker to get the offsets for the headers
  1199.     for(field = 0; field < 2; field++)
  1200.     {
  1201.         done = 0;
  1202.         while(!done)
  1203.         {
  1204.             marker = next_marker(buffer, 
  1205.                 &offset, 
  1206.                 buffer_size);
  1207.             len = 0;
  1208.  
  1209.             switch(marker)
  1210.             {
  1211.                 case M_SOI:
  1212. // The first field may be padded
  1213.                     if(field > 0) 
  1214.                         header[0].next_offset = offset - 2;
  1215.                     len = 0;
  1216.                     break;
  1217.  
  1218.                 case M_DHT:
  1219.                     header[field].huffman_offset = offset - 2;
  1220.                     len = next_int16(buffer, &offset, buffer_size);
  1221.                     break;
  1222.  
  1223.                 case M_DQT:
  1224.                     header[field].quant_offset = offset - 2;
  1225.                     len = next_int16(buffer, &offset, buffer_size);
  1226.                     break;
  1227.                 
  1228.                 case M_SOF0:
  1229.                     header[field].image_offset = offset - 2;
  1230.                     len = next_int16(buffer, &offset, buffer_size);
  1231.                     break;
  1232.                 
  1233.                 case M_SOS:
  1234.                     header[field].scan_offset = offset - 2;
  1235.                     len = next_int16(buffer, &offset, buffer_size);
  1236.                     header[field].data_offset = offset + len + 2;
  1237.                     done = 1;
  1238.                     break;
  1239.                 
  1240.                 case 0:
  1241.                 case M_EOI:
  1242.                     header[field].field_size = 
  1243.                         header[field].padded_field_size = 
  1244.                         offset;
  1245.                     if(field > 0) header[field].next_offset = 0;
  1246.                     done = 1;
  1247.                     break;
  1248.  
  1249.                 default:
  1250.                     len = next_int16(buffer, &offset, buffer_size);
  1251.                     break;
  1252.             }
  1253.  
  1254.             if(!done) offset += len;
  1255.         }
  1256.     }
  1257. }
  1258.  
  1259. static void insert_quicktime_marker(unsigned char *buffer, 
  1260.     long buffer_size, 
  1261.     long offset, 
  1262.     mjpeg_qt_hdr *header)
  1263. {
  1264.     write_int32(buffer, &offset, buffer_size, 0xff000000 | ((unsigned long)M_APP1 << 16) | (QUICKTIME_MARKER_SIZE - 2));
  1265.     write_int32(buffer, &offset, buffer_size, 0);
  1266.     write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
  1267.     write_int32(buffer, &offset, buffer_size, header->field_size);
  1268.     write_int32(buffer, &offset, buffer_size, header->padded_field_size);
  1269.     write_int32(buffer, &offset, buffer_size, header->next_offset);
  1270.     write_int32(buffer, &offset, buffer_size, header->quant_offset);
  1271.     write_int32(buffer, &offset, buffer_size, header->huffman_offset);
  1272.     write_int32(buffer, &offset, buffer_size, header->image_offset);
  1273.     write_int32(buffer, &offset, buffer_size, header->scan_offset);
  1274.     write_int32(buffer, &offset, buffer_size, header->data_offset);
  1275. }
  1276.  
  1277.  
  1278. void mjpeg_insert_quicktime_markers(unsigned char **buffer, 
  1279.     long *buffer_size, 
  1280.     long *buffer_allocated,
  1281.     int fields)
  1282. {
  1283.     mjpeg_qt_hdr header[2];
  1284.  
  1285.     if(fields < 2) return;
  1286. // Get offsets for tables in both fields
  1287.     table_offsets(*buffer, *buffer_size, header);
  1288.  
  1289.     header[0].field_size += QUICKTIME_MARKER_SIZE;
  1290.     header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
  1291.     header[0].next_offset += QUICKTIME_MARKER_SIZE;
  1292.     header[1].field_size += QUICKTIME_MARKER_SIZE;
  1293.     header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
  1294. // Insert APP1 marker
  1295.     insert_space(buffer, 
  1296.         buffer_size, 
  1297.         buffer_allocated,
  1298.         2,
  1299.         QUICKTIME_MARKER_SIZE);
  1300.     insert_quicktime_marker(*buffer, 
  1301.         *buffer_size, 
  1302.         2, 
  1303.         &header[0]);
  1304.  
  1305.     insert_space(buffer, 
  1306.         buffer_size, 
  1307.         buffer_allocated,
  1308.         header[0].next_offset + 2,
  1309.         QUICKTIME_MARKER_SIZE);
  1310.     header[1].next_offset = 0;
  1311.     insert_quicktime_marker(*buffer, 
  1312.         *buffer_size, 
  1313.         header[0].next_offset + 2, 
  1314.         &header[1]);
  1315. }
  1316.  
  1317.  
  1318. static void read_quicktime_markers(unsigned char *buffer, 
  1319.     long buffer_size, 
  1320.     mjpeg_qt_hdr *header)
  1321. {
  1322.     long offset = 0;
  1323.     int marker_count = 0;
  1324.     int result = 0;
  1325.  
  1326.     while(marker_count < 2 && offset < buffer_size && !result)
  1327.     {
  1328.         result = find_marker(buffer, 
  1329.             &offset, 
  1330.             buffer_size,
  1331.             M_APP1);
  1332.  
  1333.         if(!result)
  1334.         {
  1335. // Marker size
  1336.             next_int16(buffer, &offset, buffer_size);
  1337. // Zero
  1338.             next_int32(buffer, &offset, buffer_size);
  1339. // MJPA
  1340.             next_int32(buffer, &offset, buffer_size);
  1341. // Information
  1342.             header[marker_count].field_size = next_int32(buffer, &offset, buffer_size);
  1343.             header[marker_count].padded_field_size = next_int32(buffer, &offset, buffer_size);
  1344.             header[marker_count].next_offset = next_int32(buffer, &offset, buffer_size);
  1345.             header[marker_count].quant_offset = next_int32(buffer, &offset, buffer_size);
  1346.             header[marker_count].huffman_offset = next_int32(buffer, &offset, buffer_size);
  1347.             header[marker_count].image_offset = next_int32(buffer, &offset, buffer_size);
  1348.             header[marker_count].scan_offset = next_int32(buffer, &offset, buffer_size);
  1349.             header[marker_count].data_offset = next_int32(buffer, &offset, buffer_size);
  1350.             marker_count++;
  1351.         }
  1352.     }
  1353. }
  1354.  
  1355. long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
  1356. {
  1357.     mjpeg_qt_hdr header[2];
  1358.     bzero(&header, sizeof(mjpeg_qt_hdr) * 2);
  1359.  
  1360.     read_quicktime_markers(buffer, buffer_size, header);
  1361.     return header[0].next_offset;
  1362. }
  1363.  
  1364. long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
  1365. {
  1366.     long result = 0;
  1367.     int total_fields = 0;
  1368.     long offset = 0;
  1369.     long field2_offset = 0;
  1370.     int i;
  1371.  
  1372.     while(total_fields < 2)
  1373.     {
  1374.         int result = find_marker(buffer, 
  1375.             &offset, 
  1376.             buffer_size,
  1377.             M_SOI);
  1378.         if(!result) 
  1379.         {
  1380.             total_fields++;
  1381.             field2_offset = offset - 2;
  1382.         }
  1383.         else
  1384.         {
  1385.             field2_offset = 0;
  1386.             break;
  1387.         }
  1388.     }
  1389.  
  1390.     return field2_offset;
  1391. }
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.