"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/rle.c" (9 Jan 2007, 4541 Bytes) of package /linux/privat/old/quicktime4linux-2.3-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* RLE codec */
    2 
    3 #include "colormodels.h"
    4 #include "funcprotos.h"
    5 #include "quicktime.h"
    6 
    7 
    8 typedef struct
    9 {
   10     unsigned char *work_buffer;
   11     int buffer_size;
   12     unsigned char *output_temp;
   13 } quicktime_rle_codec_t;
   14 
   15 
   16 static int delete_codec(quicktime_video_map_t *vtrack)
   17 {
   18     quicktime_rle_codec_t *codec;
   19     codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   20     if(codec->work_buffer) free(codec->work_buffer);
   21     if(codec->output_temp) free(codec->output_temp);
   22     free(codec);
   23 }
   24 
   25 static int reads_colormodel(quicktime_t *file, 
   26         int colormodel, 
   27         int track)
   28 {
   29     return (colormodel == BC_RGB888);
   30 }
   31 
   32 static int source_cmodel(quicktime_t *file, int track)
   33 {
   34     int depth = quicktime_video_depth(file, track);
   35     if(depth == 24) 
   36         return BC_RGB888;
   37     else
   38         return BC_ARGB8888;
   39 }
   40 
   41 
   42 
   43 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
   44 {
   45     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
   46     quicktime_trak_t *trak = vtrack->track;
   47     quicktime_rle_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   48     int depth = quicktime_video_depth(file, track);
   49     int width = trak->tkhd.track_width;
   50     int height = trak->tkhd.track_height;
   51     int size;
   52     int result = 0;
   53     unsigned char *ptr;
   54     int start_line;
   55     int total_lines;
   56     int header;
   57     int row_bytes;
   58     int pixel_size;
   59     unsigned char *row_ptr;
   60     unsigned char *pixel;
   61     unsigned char *buffer_end;
   62     int code;
   63     int r, g, b, i;
   64     int need_temp;
   65     unsigned char **temp_rows = malloc(sizeof(unsigned char*) * height);
   66     int cmodel = source_cmodel(file, track);
   67     int skip;
   68 
   69     quicktime_set_video_position(file, vtrack->current_position, track);
   70     size = quicktime_frame_size(file, vtrack->current_position, track);
   71     row_bytes = depth / 8 * width;
   72     pixel_size = depth / 8;
   73 
   74     if(size <= 8) return 0;
   75     if(codec->buffer_size < size && codec->work_buffer)
   76     {
   77         free(codec->work_buffer);
   78         codec->work_buffer = 0;
   79     }
   80     if(!codec->work_buffer)
   81     {
   82         codec->work_buffer = malloc(size);
   83         codec->buffer_size = size;
   84     }
   85 
   86     if(!quicktime_read_data(file, 
   87         codec->work_buffer, 
   88         size))
   89         result = -1;
   90 
   91     ptr = codec->work_buffer;
   92     buffer_end = ptr + size;
   93 
   94 // Chunk size
   95     ptr += 4;
   96 
   97 // Header
   98     header = (ptr[0] << 8) | ptr[1];
   99     ptr += 2;
  100 
  101 // Incremental change
  102     if(header & 0x0008)
  103     {
  104         start_line = (ptr[0] << 8) | ptr[1];
  105         ptr += 4;
  106         total_lines = (ptr[0] << 8) | ptr[1];
  107         ptr += 4;
  108     }
  109     else
  110 // Keyframe
  111     {
  112         start_line = 0;
  113         total_lines = height;
  114     }
  115 
  116 
  117     if(cmodel != file->color_model ||
  118         file->in_x != 0 ||
  119         file->in_y != 0 ||
  120         file->in_w != width ||
  121         file->in_h != height ||
  122         file->out_w != width ||
  123         file->out_h != height)
  124         need_temp = 1;
  125 
  126     if(need_temp)
  127     {
  128         if(!codec->output_temp)
  129             codec->output_temp = calloc(1, height * row_bytes);
  130         row_ptr = codec->output_temp + start_line * row_bytes;
  131         for(i = 0; i < height; i++)
  132             temp_rows[i] = codec->output_temp + i * row_bytes;
  133     }
  134     else
  135     {
  136         row_ptr = row_pointers[start_line];
  137         for(i = 0; i < height; i++)
  138             temp_rows[i] = row_pointers[i];
  139     }
  140 
  141     switch(depth)
  142     {
  143         case 24:
  144             while(total_lines--)
  145             {
  146                 skip = *ptr++;
  147                 pixel = row_ptr + (skip - 1) * pixel_size;
  148 
  149                 while(ptr < buffer_end && 
  150                     (code = (char)*ptr++) != -1)
  151                 {
  152                     if(code == 0)
  153                     {
  154 // Skip code
  155                         pixel += (*ptr++ - 1) * pixel_size;
  156                     }
  157                     else
  158 // Run length encoded
  159                     if(code < 0)
  160                     {
  161                         code *= -1;
  162                         r = *ptr++;
  163                         g = *ptr++;
  164                         b = *ptr++;
  165                         while(code--)
  166                         {
  167                             *pixel++ = r;
  168                             *pixel++ = g;
  169                             *pixel++ = b;
  170                         }
  171                     }
  172                     else
  173 // Uncompressed
  174                     {
  175                         while(code--)
  176                         {
  177                             *pixel++ = *ptr++;
  178                             *pixel++ = *ptr++;
  179                             *pixel++ = *ptr++;
  180                         }
  181                     }       
  182                 }
  183 
  184 
  185                 row_ptr += row_bytes;
  186             }
  187             break;
  188     }
  189 
  190 
  191     if(need_temp)
  192     {
  193         cmodel_transfer(row_pointers, 
  194             temp_rows,
  195             row_pointers[0],
  196             row_pointers[1],
  197             row_pointers[2],
  198             0,
  199             0,
  200             0,
  201             file->in_x, 
  202             file->in_y, 
  203             file->in_w, 
  204             file->in_h,
  205             0, 
  206             0, 
  207             file->out_w, 
  208             file->out_h,
  209             cmodel, 
  210             file->color_model,
  211             0,
  212             width,
  213             file->out_w);
  214     }
  215 
  216     free(temp_rows);
  217 
  218     return 0;
  219 }
  220 
  221 
  222 
  223 void quicktime_init_codec_rle(quicktime_video_map_t *vtrack)
  224 {
  225     quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
  226     quicktime_rle_codec_t *codec;
  227     codec_base->priv = calloc(1, sizeof(quicktime_rle_codec_t));
  228     codec_base->delete_vcodec = delete_codec;
  229     codec_base->decode_video = decode;
  230     codec_base->reads_colormodel = reads_colormodel;
  231     codec_base->fourcc = "rle ";
  232     codec_base->title = "RLE";
  233     codec_base->desc = "Run length encoding";
  234 
  235     codec = (quicktime_rle_codec_t*)codec_base->priv;
  236 }
  237