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 / wmx1.c < prev    next >
C/C++ Source or Header  |  2000-11-29  |  9KB  |  298 lines

  1. #include "quicktime.h"
  2. #include "jpeglib.h"
  3.  
  4. #define ABS(x) ((x) < 0 ? -(x) : (x)) 
  5.  
  6. int quicktime_init_codec_wmx1(quicktime_video_map_t *vtrack)
  7. {
  8.     int i;
  9.     quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
  10.  
  11.     quicktime_init_yuv(&(codec->yuv_tables));
  12.     codec->bytes_per_line = vtrack->track->tkhd.track_width * 3;
  13.     if((float)codec->bytes_per_line / 6 > (int)(codec->bytes_per_line / 6))
  14.         codec->bytes_per_line += 3;
  15.  
  16.     codec->rows = vtrack->track->tkhd.track_height / 2;
  17.     if((float)vtrack->track->tkhd.track_height / 2 > (int)(vtrack->track->tkhd.track_height / 2))
  18.         codec->rows++;
  19.  
  20.     for(i = 0; i < WMX_CHUNK_FRAMES; i++)
  21.         codec->frame_cache[i] = 0;
  22.  
  23.     codec->key_frame = 0;
  24.     codec->keyframe_position = 0;
  25.     codec->quality = 100;
  26.     codec->use_float = 0;
  27.     codec->frames_per_chunk = 0;
  28.     codec->threshold = 5;
  29.     return 0;
  30. }
  31.  
  32. int quicktime_delete_codec_wmx1(quicktime_video_map_t *vtrack)
  33. {
  34.     int i;
  35.     quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
  36.  
  37.     quicktime_delete_yuv(&(codec->yuv_tables));
  38.     for(i = 0; i < WMX_CHUNK_FRAMES; i++)
  39.         if(codec->frame_cache[i]) free(codec->frame_cache[i]);
  40.  
  41.     if(codec->key_frame) free(codec->key_frame);
  42.     return 0;
  43. }
  44.  
  45. int wmx1_write_cache(quicktime_t *file, int track)
  46. {
  47.     long offset = quicktime_position(file);
  48.     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  49.     quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
  50.     int width = codec->bytes_per_line;
  51.     int height = codec->rows;
  52.     int result = 0;
  53.     int frame, channel, i, j, k;
  54.     long bytes_per_row = codec->bytes_per_line;
  55.     int step = codec->frames_per_chunk * bytes_per_row;
  56.     long bytes = height * bytes_per_row * codec->frames_per_chunk;
  57.     long output_bytes;
  58.     unsigned char *input_row, *input_end, *output_row, *input_frame, *output_frame;
  59.  
  60. /*printf("wmx1_write_cache 1 %d %d %d\n", bytes_per_row, bytes_per_channel, bytes); */
  61.     if(!codec->key_frame)
  62.     {
  63.         codec->key_frame = malloc(bytes);
  64.         if(!codec->key_frame) result = 1;
  65.     }
  66. /*printf("wmx1_write_cache 2\n"); */
  67.  
  68. /* Interlace rows */
  69.     for(frame = 0; frame < codec->frames_per_chunk; frame++)
  70.     {
  71.         input_frame = codec->frame_cache[frame];
  72.         output_frame = codec->key_frame + frame * bytes_per_row;
  73.         input_row = input_frame;
  74.         output_row = output_frame;
  75.  
  76.         for(i = 0; i < height; i++)
  77.         {
  78.             for(j = 0; j < width; j++)
  79.             {
  80.                 output_row[j] = input_row[j];
  81.             }
  82.             output_row += step;
  83.             input_row += bytes_per_row;
  84.         }
  85.     }
  86.  
  87. /* Write as a jpeg */
  88. /*     { */
  89. /*         struct jpeg_compress_struct jpeg_compress; */
  90. /*         struct jpeg_error_mgr jpeg_error; */
  91. /*         JSAMPROW row_pointer[1]; */
  92. /*         jpeg_compress.err = jpeg_std_error(&jpeg_error); */
  93. /*         jpeg_create_compress(&jpeg_compress); */
  94. /*         jpeg_stdio_dest(&jpeg_compress, quicktime_get_fd(file)); */
  95. /*         jpeg_compress.image_width = bytes_per_row; */
  96. /*         jpeg_compress.image_height = height * codec->frames_per_chunk; */
  97. /*         jpeg_compress.input_components = 1; */
  98. /*         jpeg_compress.in_color_space = JCS_GRAYSCALE; */
  99. /*         jpeg_set_defaults(&jpeg_compress); */
  100. /*         jpeg_set_quality(&jpeg_compress, codec->quality, 0); */
  101. /*         jpeg_start_compress(&jpeg_compress, TRUE); */
  102. /*         while(jpeg_compress.next_scanline < jpeg_compress.image_height && !result) */
  103. /*         { */
  104. /*             row_pointer[0] = codec->key_frame + jpeg_compress.next_scanline * bytes_per_row; */
  105. /*             result = jpeg_write_scanlines(&jpeg_compress, row_pointer, 1); */
  106. /*             result = !result; */
  107. /*         } */
  108. /*         jpeg_finish_compress(&jpeg_compress); */
  109. /*         jpeg_destroy((j_common_ptr)&jpeg_compress); */
  110. /*     } */
  111.  
  112. /* Write as raw */
  113.     result = quicktime_write_data(file, codec->key_frame, bytes);
  114.     result = !result;
  115. /*printf("wmx1_write_cache 4\n"); */
  116.  
  117.     output_bytes = quicktime_position(file) - offset;
  118.     quicktime_update_tables(file,
  119.                         vtrack->track,
  120.                         offset,
  121.                         vtrack->current_chunk,
  122.                         vtrack->current_position,
  123.                         codec->frames_per_chunk,
  124.                         output_bytes);
  125. /*printf("wmx1_write_cache 5\n"); */
  126.  
  127.     codec->frames_per_chunk = 0;
  128.     vtrack->current_chunk++;
  129.     return result;
  130. }
  131.  
  132. /* Perform YUV transform and store in cache */
  133. int wmx1_store_in_cache(quicktime_t *file, unsigned char *cache, unsigned char **row_pointers, int track)
  134. {
  135.     long offset = quicktime_position(file);
  136.     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  137.     quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
  138.     quicktime_yuv_t *yuv_tables = &(codec->yuv_tables);
  139.     int result = 0;
  140.     int width = vtrack->track->tkhd.track_width;
  141.     int height = vtrack->track->tkhd.track_height;
  142.     long bytes = codec->rows * codec->bytes_per_line;
  143.     unsigned char *buffer = cache;
  144.     unsigned char *output_row;    /* Pointer to output row */
  145.     unsigned char *row_pointer1, *row_pointer2;  /* Pointers to input rows */
  146.     int x1, x2, in_y, out_y;
  147.     int y1, y2, y3, y4, u, v;
  148.     int r, g, b;
  149.     int endpoint = width * 3;
  150.     int denominator;
  151.  
  152.     for(in_y = 0, out_y = 0; in_y < height; out_y++)
  153.     {
  154.         output_row = buffer + out_y * codec->bytes_per_line;
  155.         row_pointer1 = row_pointers[in_y];
  156.         in_y++;
  157.  
  158.         if(in_y < height)
  159.             row_pointer2 = row_pointers[in_y];
  160.         else
  161.             row_pointer2 = row_pointer1;
  162.  
  163.         in_y++;
  164.  
  165.         for(x1 = 0, x2 = 0; x1 < endpoint; )
  166.         {
  167. /* Top left pixel */
  168.             r = row_pointer1[x1++];
  169.             g = row_pointer1[x1++];
  170.             b = row_pointer1[x1++];
  171.  
  172.             y1 = (yuv_tables->rtoy_tab[r] + yuv_tables->gtoy_tab[g] + yuv_tables->btoy_tab[b]);
  173.             u = (yuv_tables->rtou_tab[r] + yuv_tables->gtou_tab[g] + yuv_tables->btou_tab[b]);
  174.             v = (yuv_tables->rtov_tab[r] + yuv_tables->gtov_tab[g] + yuv_tables->btov_tab[b]);
  175.  
  176. /* Top right pixel */
  177.             if(x1 < endpoint)
  178.             {
  179.                 r = row_pointer1[x1++];
  180.                 g = row_pointer1[x1++];
  181.                 b = row_pointer1[x1++];
  182.             }
  183.  
  184.             y2 = (yuv_tables->rtoy_tab[r] + yuv_tables->gtoy_tab[g] + yuv_tables->btoy_tab[b]);
  185.             u += (yuv_tables->rtou_tab[r] + yuv_tables->gtou_tab[g] + yuv_tables->btou_tab[b]);
  186.             v += (yuv_tables->rtov_tab[r] + yuv_tables->gtov_tab[g] + yuv_tables->btov_tab[b]);
  187.  
  188. /* Bottom left pixel */
  189.             r = row_pointer2[x2++];
  190.             g = row_pointer2[x2++];
  191.             b = row_pointer2[x2++];
  192.  
  193.             y3 = (yuv_tables->rtoy_tab[r] + yuv_tables->gtoy_tab[g] + yuv_tables->btoy_tab[b]);
  194.             u += (yuv_tables->rtou_tab[r] + yuv_tables->gtou_tab[g] + yuv_tables->btou_tab[b]);
  195.             v += (yuv_tables->rtov_tab[r] + yuv_tables->gtov_tab[g] + yuv_tables->btov_tab[b]);
  196.  
  197. /* Bottom right pixel */
  198.             if(x2 < endpoint)
  199.             {
  200.                 r = row_pointer2[x2++];
  201.                 g = row_pointer2[x2++];
  202.                 b = row_pointer2[x2++];
  203.             }
  204.  
  205.             y4 = (yuv_tables->rtoy_tab[r] + yuv_tables->gtoy_tab[g] + yuv_tables->btoy_tab[b]);
  206.             u += (yuv_tables->rtou_tab[r] + yuv_tables->gtou_tab[g] + yuv_tables->btou_tab[b]);
  207.             v += (yuv_tables->rtov_tab[r] + yuv_tables->gtov_tab[g] + yuv_tables->btov_tab[b]);
  208.  
  209.             y1 /= 0x10000;
  210.             y2 /= 0x10000;
  211.             y3 /= 0x10000;
  212.             y4 /= 0x10000;
  213.             u /= 0x40000;
  214.             v /= 0x40000;
  215.             if(y1 > 255) y1 = 255;
  216.             if(y2 > 255) y2 = 255;
  217.             if(y3 > 255) y3 = 255;
  218.             if(y4 > 255) y4 = 255;
  219.             if(u > 127) u = 127;
  220.             if(v > 127) v = 127;
  221.             if(y1 < 0) y1 = 0;
  222.             if(y2 < 0) y2 = 0;
  223.             if(y3 < 0) y3 = 0;
  224.             if(y4 < 0) y4 = 0;
  225.             if(u < -128) u = -128;
  226.             if(v < -128) v = -128;
  227.  
  228.             *output_row++ = u;
  229.             *output_row++ = v;
  230.             *output_row++ = y1;
  231.             *output_row++ = y2;
  232.             *output_row++ = y3;
  233.             *output_row++ = y4;
  234.         }
  235.     }
  236.     return 0;
  237. }
  238.  
  239. int quicktime_encode_wmx1(quicktime_t *file, unsigned char **row_pointers, int track)
  240. {
  241.     int result = 0;
  242.     int written_cache = 0;
  243.     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  244.     quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
  245.     int width = vtrack->track->tkhd.track_width;
  246.     int height = vtrack->track->tkhd.track_height;
  247.     int bytes = codec->rows * codec->bytes_per_line;
  248.     long frame_difference = 0;
  249.     int i;
  250.  
  251. /* Arm cache */
  252.     if(codec->frames_per_chunk < WMX_CHUNK_FRAMES)
  253.     {
  254.         unsigned char *frame_cache;
  255.         unsigned char *row_pointer1, *row_pointer2, *endpoint;
  256.         if(!codec->frame_cache[codec->frames_per_chunk])
  257.             codec->frame_cache[codec->frames_per_chunk] = malloc(bytes);
  258.         frame_cache = codec->frame_cache[codec->frames_per_chunk];
  259.  
  260. /* Copy to cache */
  261.         wmx1_store_in_cache(file, frame_cache, row_pointers, track);
  262.         codec->frames_per_chunk++;
  263.     }
  264.     else
  265.     {
  266. /* Write cache and start new cache. */
  267.         unsigned char *frame_cache;
  268.  
  269.         result = wmx1_write_cache(file, track);
  270.         written_cache = 1;
  271.  
  272. /* Copy next frame to cache */
  273.         if(!codec->frame_cache[codec->frames_per_chunk])
  274.             codec->frame_cache[codec->frames_per_chunk] = malloc(bytes);
  275.         frame_cache = codec->frame_cache[codec->frames_per_chunk];
  276.         wmx1_store_in_cache(file, codec->frame_cache[codec->frames_per_chunk], row_pointers, track);
  277.         codec->frames_per_chunk++;
  278.     }
  279. /*printf("quicktime_encode_wmx1 3\n"); */
  280.  
  281. /*     if(!written_cache) */
  282. /*         quicktime_update_tables(file, */
  283. /*                        vtrack->track, */
  284. /*                         offset, */
  285. /*                         vtrack->current_chunk, */
  286. /*                         vtrack->current_position, */
  287. /*                         codec->frames_per_chunk, */
  288. /*                         output_bytes); */
  289. /*  */
  290.     return result;
  291. }
  292.  
  293. int quicktime_decode_wmx1(quicktime_t *file, unsigned char **row_pointers, int track)
  294. {
  295.     int result = 0;
  296.     return result;
  297. }
  298.