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 / raw.c < prev    next >
C/C++ Source or Header  |  2000-11-29  |  10KB  |  374 lines

  1. #include "colormodels.h"
  2. #include "quicktime.h"
  3. #include "raw.h"
  4. #include "funcprotos.h"
  5.  
  6. static int quicktime_delete_codec_raw(quicktime_video_map_t *vtrack)
  7. {
  8.     quicktime_raw_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  9.     if(codec->temp_frame)
  10.     {
  11.         free(codec->temp_rows);
  12.         free(codec->temp_frame);
  13.     }
  14.     free(codec);
  15.     return 0;
  16. }
  17.  
  18. static int quicktime_decode_raw(quicktime_t *file, unsigned char **row_pointers, int track)
  19. {
  20.     int result = 0;
  21.     quicktime_trak_t *trak = file->vtracks[track].track;
  22.     int frame_depth = quicktime_video_depth(file, track);
  23.     int track_height = trak->tkhd.track_height;
  24.     int track_width = trak->tkhd.track_width;
  25.     long bytes;
  26.     quicktime_raw_codec_t *codec = ((quicktime_codec_t*)file->vtracks[track].codec)->priv;
  27.     int pixel_size = frame_depth / 8;
  28.     long bytes_per_row = track_width * pixel_size;
  29.  
  30.     if(codec->scaletable)
  31.     {
  32.         if(codec->scaletable && 
  33.             quicktime_compare_scaletable(codec->scaletable, file->in_w, file->in_h, file->out_w, file->out_h))
  34.         {
  35.             quicktime_delete_scaletable(codec->scaletable);
  36.             codec->scaletable = 0;
  37.         }
  38.     }
  39.     
  40.     if(!codec->scaletable)
  41.     {
  42.         codec->scaletable = quicktime_new_scaletable(file->in_w, file->in_h, file->out_w, file->out_h);
  43.     }
  44.  
  45. /* Read data */
  46.     quicktime_set_video_position(file, file->vtracks[track].current_position, track);
  47.     bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track);
  48.  
  49. /* Read data directly into output */
  50.     if(quicktime_identity_scaletable(codec->scaletable) && 
  51.         ((file->color_model == BC_RGB888 && frame_depth == 24) || 
  52.         (file->color_model == BC_BGR8888 && frame_depth == 32) ||
  53.         (file->color_model == BC_RGBA8888 && frame_depth == 32)))
  54.     {
  55.         result = !quicktime_read_data(file, row_pointers[0], bytes);
  56.  
  57. /* Swap bytes */
  58. /* ARGB to RGBA */
  59.         if(file->color_model == BC_RGBA8888)
  60.         {
  61.             register unsigned char temp;
  62.             register int i, j;
  63.             for(i = 0; i < track_height; i++)
  64.             {
  65.                 for(j = 0; j < bytes_per_row; j += 4)
  66.                 {
  67.                     temp = row_pointers[i][j];
  68.                     row_pointers[i][j] = row_pointers[i][j + 1];
  69.                     row_pointers[i][j + 1] = row_pointers[i][j + 2];
  70.                     row_pointers[i][j + 2] = row_pointers[i][j + 3];
  71.                     row_pointers[i][j + 3] = temp;
  72.                 }
  73.             }
  74.         }
  75.         else
  76. /* ARGB to BGR */
  77.         if(file->color_model == BC_BGR8888)
  78.         {
  79.             register unsigned char temp;
  80.             register int i, j;
  81.             for(i = 0; i < track_height; i++)
  82.             {
  83.                 for(j = 0; j < bytes_per_row; j += 4)
  84.                 {
  85.                     temp = row_pointers[i][j];
  86.                     row_pointers[i][j] = row_pointers[i][j + 2];
  87.                     row_pointers[i][j + 2] = temp;
  88.                 }
  89.             }
  90.         }
  91.     }
  92.     else
  93. /* Read data into temp frame */
  94. /* Eventually this should be put into graphics.c */
  95.     {
  96.         int i, j;
  97.         unsigned char *input_row, *output_row;
  98.  
  99.         if(!codec->temp_frame)
  100.         {
  101.             codec->temp_frame = calloc(1, pixel_size * track_width * track_height);
  102.             codec->temp_rows = calloc(1, sizeof(unsigned char*) * track_height);
  103.             for(i = 0; i < track_height; i++) codec->temp_rows[i] = &codec->temp_frame[i * pixel_size * track_width];
  104.         }
  105.  
  106.         result = !quicktime_read_data(file, codec->temp_frame, bytes);
  107.  
  108. /* Scale rows */
  109.         for(i = 0; i < file->out_h; i++)
  110.         {
  111.             input_row = codec->temp_rows[codec->scaletable->input_y[i] + file->in_y] + pixel_size * file->in_x;
  112.             output_row = row_pointers[i];
  113.  
  114. /* Scale columns */
  115.             if(file->out_w != file->in_w)
  116.             {
  117.                 switch(file->color_model)
  118.                 {
  119.                     case BC_RGB888:
  120. /* ARGB to RGB */
  121.                         if(frame_depth == 32)
  122.                         {
  123.                             for(j = 0; j < file->out_w; j++)
  124.                             {
  125.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 1;
  126.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 2;
  127.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 3;
  128.                             }
  129.                         }
  130.                         else
  131. /* RGB to RGB */
  132.                         if(frame_depth == 24)
  133.                         {
  134.                             for(j = 0; j < file->out_w; j++)
  135.                             {
  136.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size];
  137.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 1;
  138.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 2;
  139.                             }
  140.                         }
  141.                         break;
  142.  
  143.                     case BC_BGR8888:
  144. /* ARGB to BGR0 */
  145.                         if(frame_depth == 32)
  146.                         {
  147.                             for(j = 0; j < file->out_w; j++)
  148.                             {
  149.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 3;
  150.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 2;
  151.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 1;
  152.                                 *output_row++;
  153.                             }
  154.                         }
  155.                         else
  156. /* RGB to BGR0 */
  157.                         if(frame_depth == 24)
  158.                         {
  159.                             for(j = 0; j < file->out_w; j++)
  160.                             {
  161.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 2;
  162.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 1;
  163.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size];
  164.                             }
  165.                         }
  166.                         break;
  167.  
  168.                     case BC_RGBA8888:
  169. /* ARGB to RGBA */
  170.                         if(frame_depth == 32)
  171.                         {
  172.                             for(j = 0; j < file->out_w; j++)
  173.                             {
  174.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 1;
  175.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 2;
  176.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 3;
  177.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size];
  178.                             }
  179.                         }
  180.                         else
  181. /* RGB to RGBA */
  182.                         if(frame_depth == 24)
  183.                         {
  184.                             for(j = 0; j < file->out_w; j++)
  185.                             {
  186.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size];
  187.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 1;
  188.                                 *output_row++ = input_row[codec->scaletable->input_x[j] * pixel_size] + 2;
  189.                                 *output_row++ = 255;
  190.                             }
  191.                         }
  192.                         break;
  193.                 }
  194.             }
  195.             else
  196. /* Copy columns directly */
  197.             {
  198.                 switch(file->color_model)
  199.                 {
  200.                     case BC_RGB888:
  201. /* ARGB to RGB */
  202.                         if(frame_depth == 32)
  203.                         {
  204.                             input_row++;
  205.                             for(j = 0; j < file->out_w; j++)
  206.                             {
  207.                                 *output_row++ = *input_row++;
  208.                                 *output_row++ = *input_row++;
  209.                                 *output_row++ = *input_row++;
  210.                                 input_row++;
  211.                             }
  212.                         }
  213.                         else
  214. /* RGB to RGB */
  215.                         if(frame_depth == 24)
  216.                         {
  217.                             memcpy(output_row, input_row, pixel_size * file->out_w);
  218.                         }
  219.                         break;
  220.  
  221.                     case BC_BGR8888:
  222. /* ARGB to BGR0 */
  223.                         if(frame_depth == 32)
  224.                         {
  225.                             for(j = 0; j < file->out_w; j++)
  226.                             {
  227.                                 *output_row++ = input_row[3];
  228.                                 *output_row++ = input_row[2];
  229.                                 *output_row++ = input_row[1];
  230.                                 *output_row++;
  231.                                 input_row += 4;
  232.                             }
  233.                         }
  234.                         else
  235. /* RGB to BGR0 */
  236.                         if(frame_depth == 24)
  237.                         {
  238.                             for(j = 0; j < file->out_w; j++)
  239.                             {
  240.                                 *output_row++ = input_row[2];
  241.                                 *output_row++ = input_row[1];
  242.                                 *output_row++ = input_row[0];
  243.                                 input_row += 3;
  244.                             }
  245.                         }
  246.                         break;
  247.  
  248.                     case BC_RGBA8888:
  249. /* ARGB to RGBA */
  250.                         if(frame_depth == 32)
  251.                         {
  252.                             for(j = 0; j < file->out_w; j++)
  253.                             {
  254.                                 *output_row++ = input_row[1];
  255.                                 *output_row++ = input_row[2];
  256.                                 *output_row++ = input_row[3];
  257.                                 *output_row++ = input_row[0];
  258.                                 input_row += 4;
  259.                             }
  260.                         }
  261.                         else
  262. /* RGB to RGBA */
  263.                         if(frame_depth == 24)
  264.                         {
  265.                             for(j = 0; j < file->out_w; j++)
  266.                             {
  267.                                 *output_row++ = input_row[0];
  268.                                 *output_row++ = input_row[1];
  269.                                 *output_row++ = input_row[2];
  270.                                 *output_row++ = 255;
  271.                                 input_row += 3;
  272.                             }
  273.                         }
  274.                         break;
  275.                 }
  276.             }
  277.         }
  278.     }
  279.  
  280.     return result;
  281. }
  282.  
  283. static int quicktime_encode_raw(quicktime_t *file, unsigned char **row_pointers, int track)
  284. {
  285.     long offset = quicktime_position(file);
  286.     int result = 0;
  287.     register int i, j;
  288.     quicktime_trak_t *trak = file->vtracks[track].track;
  289.     int height = trak->tkhd.track_height;
  290.     int width = trak->tkhd.track_width;
  291.     int depth = quicktime_video_depth(file, track);
  292.     long bytes = height * width * depth / 8;
  293.     long bytes_per_row = width * depth / 8;
  294.     unsigned char temp;
  295.  
  296.     if(depth == 32)
  297.     {
  298. /* Swap byte order to match Quicktime's ARGB. */
  299.         for(i = 0; i < height; i++)
  300.         {
  301.             for(j = 0; j < bytes_per_row; j += 4)
  302.             {
  303.                 temp = row_pointers[i][j + 3];
  304.                 row_pointers[i][j + 3] = row_pointers[i][j + 2];
  305.                 row_pointers[i][j + 2] = row_pointers[i][j + 1];
  306.                 row_pointers[i][j + 1] = row_pointers[i][j];
  307.                 row_pointers[i][j] = temp;
  308.             }
  309.         }
  310.         result = !quicktime_write_data(file, row_pointers[0], bytes);
  311.     }
  312.     else
  313.     {
  314.         if(quicktime_raw_rows_consecutive(row_pointers, width, height, depth / 8))
  315.         {
  316. /* Rows are consecutive so write as a block */
  317.             result = quicktime_write_data(file, row_pointers[0], bytes);
  318.             if(result) result = 0; else result = 1;
  319.         }
  320.         else
  321.         for(i = 0; i < height && !result; i++)
  322.         {
  323. /* Rows aren't consecutive but this should never happen. */
  324.             result = quicktime_write_data(file, row_pointers[i], width * depth / 8);
  325.             if(result) result = 0; else result = 1;
  326.         }
  327.     }
  328.  
  329.     quicktime_update_tables(file,
  330.                         file->vtracks[track].track,
  331.                         offset,
  332.                         file->vtracks[track].current_chunk,
  333.                         file->vtracks[track].current_position,
  334.                         1,
  335.                         bytes);
  336.  
  337.     file->vtracks[track].current_chunk++;
  338.     return result;
  339. }
  340.  
  341. int quicktime_raw_rows_consecutive(unsigned char **row_pointers, int w, int h, int depth)
  342. {
  343.     int i, result;
  344. /* see if row_pointers are consecutive */
  345.     for(i = 1, result = 1; i < h; i++)
  346.     {
  347.         if(row_pointers[i] - row_pointers[i - 1] != w * depth) result = 0;
  348.     }
  349.     return result;
  350. }
  351.  
  352. static int quicktime_reads_colormodel_raw(quicktime_t *file, 
  353.         int colormodel, 
  354.         int track)
  355. {
  356.     return (colormodel == BC_RGB888 ||
  357.         colormodel == BC_BGR8888);
  358. }
  359.  
  360. void quicktime_init_codec_raw(quicktime_video_map_t *vtrack)
  361. {
  362.     quicktime_raw_codec_t *priv;
  363.  
  364.     ((quicktime_codec_t*)vtrack->codec)->priv = calloc(1, sizeof(quicktime_raw_codec_t));
  365.     ((quicktime_codec_t*)vtrack->codec)->delete_vcodec = quicktime_delete_codec_raw;
  366.     ((quicktime_codec_t*)vtrack->codec)->decode_video = quicktime_decode_raw;
  367.     ((quicktime_codec_t*)vtrack->codec)->encode_video = quicktime_encode_raw;
  368.     ((quicktime_codec_t*)vtrack->codec)->decode_audio = 0;
  369.     ((quicktime_codec_t*)vtrack->codec)->encode_audio = 0;
  370.     ((quicktime_codec_t*)vtrack->codec)->reads_colormodel = quicktime_reads_colormodel_raw;
  371.  
  372.     priv = ((quicktime_codec_t*)vtrack->codec)->priv;
  373. }
  374.