"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/yuv4.c" (9 Jan 2007, 10129 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 #include "colormodels.h"
    2 #include "funcprotos.h"
    3 #include "quicktime.h"
    4 #include "yuv4.h"
    5 
    6 /* U V values are signed but Y R G B values are unsigned! */
    7 /*
    8  *      R = Y               + 1.40200 * V
    9  *      G = Y - 0.34414 * U - 0.71414 * V
   10  *      B = Y + 1.77200 * U
   11  */
   12 
   13 /*
   14  *      Y =  0.2990 * R + 0.5870 * G + 0.1140 * B
   15  *      U = -0.1687 * R - 0.3310 * G + 0.5000 * B
   16  *      V =  0.5000 * R - 0.4187 * G - 0.0813 * B  
   17  */
   18 
   19 
   20 /* Now storing data as rows of UVYYYYUVYYYY */
   21 typedef struct
   22 {
   23     int use_float;
   24     long rtoy_tab[256], gtoy_tab[256], btoy_tab[256];
   25     long rtou_tab[256], gtou_tab[256], btou_tab[256];
   26     long rtov_tab[256], gtov_tab[256], btov_tab[256];
   27 
   28     long vtor_tab[256], vtog_tab[256];
   29     long utog_tab[256], utob_tab[256];
   30     long *vtor, *vtog, *utog, *utob;
   31     
   32     unsigned char *work_buffer;
   33 
   34 /* The YUV4 codec requires a bytes per line that is a multiple of 4 */
   35     int bytes_per_line;
   36 /* Actual rows encoded in the yuv4 format */
   37     int rows;
   38     int initialized;
   39 } quicktime_yuv4_codec_t;
   40 
   41 static int quicktime_delete_codec_yuv4(quicktime_video_map_t *vtrack)
   42 {
   43     quicktime_yuv4_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   44     free(codec->work_buffer);
   45     free(codec);
   46     return 0;
   47 }
   48 
   49 static int reads_colormodel(quicktime_t *file, 
   50         int colormodel, 
   51         int track)
   52 {
   53     return colormodel == BC_RGB888;
   54 }
   55 
   56 static void initialize(quicktime_video_map_t *vtrack, quicktime_yuv4_codec_t *codec)
   57 {
   58     int i;
   59     if(!codec->initialized)
   60     {
   61 /* Init private items */
   62         for(i = 0; i < 256; i++)
   63         {
   64 /* compression */
   65             codec->rtoy_tab[i] = (long)( 0.2990 * 65536 * i);
   66             codec->rtou_tab[i] = (long)(-0.1687 * 65536 * i);
   67             codec->rtov_tab[i] = (long)( 0.5000 * 65536 * i);
   68 
   69             codec->gtoy_tab[i] = (long)( 0.5870 * 65536 * i);
   70             codec->gtou_tab[i] = (long)(-0.3320 * 65536 * i);
   71             codec->gtov_tab[i] = (long)(-0.4187 * 65536 * i);
   72 
   73             codec->btoy_tab[i] = (long)( 0.1140 * 65536 * i);
   74             codec->btou_tab[i] = (long)( 0.5000 * 65536 * i);
   75             codec->btov_tab[i] = (long)(-0.0813 * 65536 * i);
   76         }
   77 
   78         codec->vtor = &(codec->vtor_tab[128]);
   79         codec->vtog = &(codec->vtog_tab[128]);
   80         codec->utog = &(codec->utog_tab[128]);
   81         codec->utob = &(codec->utob_tab[128]);
   82         for(i = -128; i < 128; i++)
   83         {
   84 /* decompression */
   85             codec->vtor[i] = (long)( 1.4020 * 65536 * i);
   86             codec->vtog[i] = (long)(-0.7141 * 65536 * i);
   87 
   88             codec->utog[i] = (long)(-0.3441 * 65536 * i);
   89             codec->utob[i] = (long)( 1.7720 * 65536 * i);
   90         }
   91         codec->bytes_per_line = vtrack->track->tkhd.track_width * 3;
   92         if((float)codec->bytes_per_line / 6 > (int)(codec->bytes_per_line / 6))
   93             codec->bytes_per_line += 3;
   94 
   95         codec->rows = vtrack->track->tkhd.track_height / 2;
   96         if((float)vtrack->track->tkhd.track_height / 2 > (int)(vtrack->track->tkhd.track_height / 2))
   97             codec->rows++;
   98 
   99         codec->work_buffer = malloc(codec->bytes_per_line * codec->rows);
  100         codec->initialized = 1;
  101     }
  102 }
  103 
  104 
  105 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
  106 {
  107     int64_t bytes, in_y, out_y;
  108     register int x1, x2;
  109     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  110     quicktime_yuv4_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  111     int width = vtrack->track->tkhd.track_width;
  112     int height = vtrack->track->tkhd.track_height;
  113     unsigned char *buffer;
  114     char *input_row;
  115     unsigned char *row_pointer1, *row_pointer2;
  116     int result = 0;
  117     int u, v;
  118     register int y1, y2, y3, y4;
  119     int r, g, b;
  120     int bytes_per_row = width * cmodel_calculate_pixelsize(file->color_model);
  121     initialize(vtrack, codec);
  122 
  123     vtrack->track->tkhd.track_width;
  124     quicktime_set_video_position(file, vtrack->current_position, track);
  125     bytes = quicktime_frame_size(file, vtrack->current_position, track);
  126     switch(file->color_model)
  127     {
  128         case BC_RGB888:
  129             buffer = codec->work_buffer;
  130             result = quicktime_read_data(file, buffer, bytes);
  131             if(result) result = 0; else result = 1;
  132 
  133             for(out_y = 0, in_y = 0; out_y < height; in_y++)
  134             {
  135                 input_row = &buffer[in_y * codec->bytes_per_line];
  136                 row_pointer1 = row_pointers[out_y++];
  137 
  138                 if(out_y < height)
  139                     row_pointer2 = row_pointers[out_y];
  140                 else
  141                     row_pointer2 = row_pointer1;
  142 
  143                 out_y++;
  144                 for(x1 = 0, x2 = 0; x1 < bytes_per_row; )
  145                 {
  146                     u = *input_row++;
  147                     v = *input_row++;
  148                     y1 = (unsigned char)*input_row++;
  149                     y2 = (unsigned char)*input_row++;
  150                     y3 = (unsigned char)*input_row++;
  151                     y4 = (unsigned char)*input_row++;
  152                     y1 <<= 16;
  153                     y2 <<= 16;
  154                     y3 <<= 16;
  155                     y4 <<= 16;
  156 
  157         /* Top left pixel */
  158                     r = ((y1 + codec->vtor[v]) >> 16);
  159                     g = ((y1 + codec->utog[u] + codec->vtog[v]) >> 16);
  160                     b = ((y1 + codec->utob[u]) >> 16);
  161                     if(r < 0) r = 0;
  162                     if(g < 0) g = 0;
  163                     if(b < 0) b = 0;
  164                     if(r > 255) r = 255;
  165                     if(g > 255) g = 255;
  166                     if(b > 255) b = 255;
  167 
  168                     row_pointer1[x1++] = r;
  169                     row_pointer1[x1++] = g;
  170                     row_pointer1[x1++] = b;
  171 
  172         /* Top right pixel */
  173                     if(x1 < bytes_per_row)
  174                     {
  175                         r = ((y2 + codec->vtor[v]) >> 16);
  176                         g = ((y2 + codec->utog[u] + codec->vtog[v]) >> 16);
  177                         b = ((y2 + codec->utob[u]) >> 16);
  178                         if(r < 0) r = 0;
  179                         if(g < 0) g = 0;
  180                         if(b < 0) b = 0;
  181                         if(r > 255) r = 255;
  182                         if(g > 255) g = 255;
  183                         if(b > 255) b = 255;
  184 
  185                         row_pointer1[x1++] = r;
  186                         row_pointer1[x1++] = g;
  187                         row_pointer1[x1++] = b;
  188                     }
  189 
  190         /* Bottom left pixel */
  191                     r = ((y3 + codec->vtor[v]) >> 16);
  192                     g = ((y3 + codec->utog[u] + codec->vtog[v]) >> 16);
  193                     b = ((y3 + codec->utob[u]) >> 16);
  194                     if(r < 0) r = 0;
  195                     if(g < 0) g = 0;
  196                     if(b < 0) b = 0;
  197                     if(r > 255) r = 255;
  198                     if(g > 255) g = 255;
  199                     if(b > 255) b = 255;
  200 
  201                     row_pointer2[x2++] = r;
  202                     row_pointer2[x2++] = g;
  203                     row_pointer2[x2++] = b;
  204 
  205         /* Bottom right pixel */
  206                     if(x2 < bytes_per_row)
  207                     {
  208                         r = ((y4 + codec->vtor[v]) >> 16);
  209                         g = ((y4 + codec->utog[u] + codec->vtog[v]) >> 16);
  210                         b = ((y4 + codec->utob[u]) >> 16);
  211                         if(r < 0) r = 0;
  212                         if(g < 0) g = 0;
  213                         if(b < 0) b = 0;
  214                         if(r > 255) r = 255;
  215                         if(g > 255) g = 255;
  216                         if(b > 255) b = 255;
  217 
  218                         row_pointer2[x2++] = r;
  219                         row_pointer2[x2++] = g;
  220                         row_pointer2[x2++] = b;
  221                     }
  222                 }
  223             }
  224             break;
  225     }
  226 
  227     return result;
  228 }
  229 
  230 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
  231 {
  232     int64_t offset = quicktime_position(file);
  233     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  234     quicktime_yuv4_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  235     quicktime_trak_t *trak = vtrack->track;
  236     int result = 0;
  237     int width = vtrack->track->tkhd.track_width;
  238     int height = vtrack->track->tkhd.track_height;
  239     int64_t bytes = codec->rows * codec->bytes_per_line;
  240     unsigned char *buffer = codec->work_buffer;
  241     unsigned char *output_row;    /* Pointer to output row */
  242     unsigned char *row_pointer1, *row_pointer2;  /* Pointers to input rows */
  243     register int x1, x2;
  244     int in_y, out_y;
  245     register int y1, y2, y3, y4;
  246     int u, v;
  247     int r, g, b;
  248     int bytes_per_row = width * 3;
  249     int denominator;
  250     quicktime_atom_t chunk_atom;
  251     initialize(vtrack, codec);
  252 
  253 
  254 
  255 
  256 
  257 
  258 
  259     for(in_y = 0, out_y = 0; in_y < height; out_y++)
  260     {
  261         output_row = buffer + out_y * codec->bytes_per_line;
  262         row_pointer1 = row_pointers[in_y];
  263         in_y++;
  264 
  265         if(in_y < height)
  266             row_pointer2 = row_pointers[in_y];
  267         else
  268             row_pointer2 = row_pointer1;
  269 
  270         in_y++;
  271 
  272         for(x1 = 0, x2 = 0; x1 < bytes_per_row; )
  273         {
  274 /* Top left pixel */
  275             r = row_pointer1[x1++];
  276             g = row_pointer1[x1++];
  277             b = row_pointer1[x1++];
  278 
  279             y1 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);
  280             u = (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);
  281             v = (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);
  282 
  283 /* Top right pixel */
  284             if(x1 < bytes_per_row)
  285             {
  286                 r = row_pointer1[x1++];
  287                 g = row_pointer1[x1++];
  288                 b = row_pointer1[x1++];
  289             }
  290 
  291             y2 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);
  292             u += (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);
  293             v += (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);
  294 
  295 /* Bottom left pixel */
  296             r = row_pointer2[x2++];
  297             g = row_pointer2[x2++];
  298             b = row_pointer2[x2++];
  299 
  300             y3 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);
  301             u += (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);
  302             v += (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);
  303 
  304 /* Bottom right pixel */
  305             if(x2 < bytes_per_row)
  306             {
  307                 r = row_pointer2[x2++];
  308                 g = row_pointer2[x2++];
  309                 b = row_pointer2[x2++];
  310             }
  311 
  312             y4 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);
  313             u += (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);
  314             v += (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);
  315 
  316             y1 /= 0x10000;
  317             y2 /= 0x10000;
  318             y3 /= 0x10000;
  319             y4 /= 0x10000;
  320             u /= 0x40000;
  321             v /= 0x40000;
  322             if(y1 > 255) y1 = 255;
  323             if(y2 > 255) y2 = 255;
  324             if(y3 > 255) y3 = 255;
  325             if(y4 > 255) y4 = 255;
  326             if(u > 127) u = 127;
  327             if(v > 127) v = 127;
  328             if(y1 < 0) y1 = 0;
  329             if(y2 < 0) y2 = 0;
  330             if(y3 < 0) y3 = 0;
  331             if(y4 < 0) y4 = 0;
  332             if(u < -128) u = -128;
  333             if(v < -128) v = -128;
  334 
  335             *output_row++ = u;
  336             *output_row++ = v;
  337             *output_row++ = y1;
  338             *output_row++ = y2;
  339             *output_row++ = y3;
  340             *output_row++ = y4;
  341         }
  342     }
  343 
  344     quicktime_write_chunk_header(file, trak, &chunk_atom);
  345     result = quicktime_write_data(file, buffer, bytes);
  346     if(result)
  347         result = 0; 
  348     else 
  349         result = 1;
  350     quicktime_write_chunk_footer(file, 
  351         trak,
  352         vtrack->current_chunk,
  353         &chunk_atom, 
  354         1);
  355 
  356 
  357     vtrack->current_chunk++;
  358     return result;
  359 }
  360 
  361 
  362 void quicktime_init_codec_yuv4(quicktime_video_map_t *vtrack)
  363 {
  364     int i;
  365     quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
  366 
  367 /* Init public items */
  368     codec_base->priv = calloc(1, sizeof(quicktime_yuv4_codec_t));
  369     codec_base->delete_vcodec = quicktime_delete_codec_yuv4;
  370     codec_base->decode_video = decode;
  371     codec_base->encode_video = encode;
  372     codec_base->decode_audio = 0;
  373     codec_base->encode_audio = 0;
  374     codec_base->reads_colormodel = reads_colormodel;
  375     codec_base->fourcc = QUICKTIME_YUV4;
  376     codec_base->title = "YUV 4:2:0 packed";
  377     codec_base->desc = "YUV 4:2:0 packed (Not standardized)";
  378 }
  379 
  380