yuv2.c
上传用户:luping1608
上传日期:2007-01-06
资源大小:38k
文件大小:6k
源码类别:

多媒体

开发平台:

Unix_Linux

  1. #include "quicktime.h"
  2. /* U V values are signed but Y R G B values are unsigned! */
  3. /*
  4.  *      R = Y               + 1.40200 * V
  5.  *      G = Y - 0.34414 * U - 0.71414 * V
  6.  *      B = Y + 1.77200 * U
  7.  */
  8. /*
  9.  * Y =  0.2990 * R + 0.5870 * G + 0.1140 * B
  10.  * U = -0.1687 * R - 0.3310 * G + 0.5000 * B
  11.  * V =  0.5000 * R - 0.4187 * G - 0.0813 * B  
  12.  */
  13. int quicktime_init_codec_yuv2(quicktime_video_map_t *vtrack)
  14. {
  15. int i;
  16. quicktime_yuv2_codec_t *codec = &(vtrack->codecs.yuv2_codec);
  17. for(i = 0; i < 256; i++)
  18. {
  19. // compression
  20. codec->rtoy_tab[i] = (long)( 0.2990 * 65536 * i);
  21. codec->rtou_tab[i] = (long)(-0.1687 * 65536 * i);
  22. codec->rtov_tab[i] = (long)( 0.5000 * 65536 * i);
  23. codec->gtoy_tab[i] = (long)( 0.5870 * 65536 * i);
  24. codec->gtou_tab[i] = (long)(-0.3320 * 65536 * i);
  25. codec->gtov_tab[i] = (long)(-0.4187 * 65536 * i);
  26. codec->btoy_tab[i] = (long)( 0.1140 * 65536 * i);
  27. codec->btou_tab[i] = (long)( 0.5000 * 65536 * i);
  28. codec->btov_tab[i] = (long)(-0.0813 * 65536 * i);
  29. }
  30. codec->vtor = &(codec->vtor_tab[128]);
  31. codec->vtog = &(codec->vtog_tab[128]);
  32. codec->utog = &(codec->utog_tab[128]);
  33. codec->utob = &(codec->utob_tab[128]);
  34. for(i = -128; i < 128; i++)
  35. {
  36. // decompression
  37. codec->vtor[i] = (long)( 1.4020 * 65536 * i);
  38. codec->vtog[i] = (long)(-0.7141 * 65536 * i);
  39. codec->utog[i] = (long)(-0.3441 * 65536 * i);
  40. codec->utob[i] = (long)( 1.7720 * 65536 * i);
  41. }
  42. codec->bytes_per_line = vtrack->track->tkhd.track_width * 2;
  43. if((float)codec->bytes_per_line / 4 > (int)(codec->bytes_per_line / 4))
  44. codec->bytes_per_line += 2;
  45. codec->work_buffer = malloc(codec->bytes_per_line *
  46. vtrack->track->tkhd.track_height);
  47. }
  48. int quicktime_delete_codec_yuv2(quicktime_video_map_t *vtrack)
  49. {
  50. free(vtrack->codecs.yuv2_codec.work_buffer);
  51. }
  52. int quicktime_decode_yuv2(quicktime_t *file, unsigned char **row_pointers, int track)
  53. {
  54. long bytes, x, y;
  55. quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  56. quicktime_yuv2_codec_t *codec = &(vtrack->codecs.yuv2_codec);
  57. int width = vtrack->track->tkhd.track_width;
  58. int height = vtrack->track->tkhd.track_height;
  59. unsigned char *buffer;
  60. char *input_row;
  61. int result = 0;
  62. int y1, u, v, y2, r, g, b;
  63. int endpoint = width * 3;
  64. vtrack->track->tkhd.track_width;
  65. quicktime_set_video_position(file, vtrack->current_position, track);
  66. bytes = quicktime_frame_size(file, vtrack->current_position, track);
  67. if(file->vtracks[track].frames_cached)
  68. {
  69. buffer = file->vtracks[track].frame_cache[vtrack->current_position];
  70. }
  71. else
  72. {
  73. buffer = codec->work_buffer;
  74. result = quicktime_read_data(file, buffer, bytes);
  75. if(result) result = 0; else result = 1;
  76. }
  77. for(y = 0; y < height; y++)
  78. {
  79. input_row = &buffer[y * codec->bytes_per_line];
  80. for(x = 0; x < endpoint; )
  81. {
  82. y1 = (unsigned char)*input_row++;
  83. u = *input_row++;
  84. y2 = (unsigned char)*input_row++;
  85. v = *input_row++;
  86. y1 <<= 16;
  87. y2 <<= 16;
  88. r = ((y1 + codec->vtor[v]) >> 16);
  89. g = ((y1 + codec->utog[u] + codec->vtog[v]) >> 16);
  90. b = ((y1 + codec->utob[u]) >> 16);
  91. if(r < 0) r = 0;
  92. if(g < 0) g = 0;
  93. if(b < 0) b = 0;
  94. if(r > 255) r = 255;
  95. if(g > 255) g = 255;
  96. if(b > 255) b = 255;
  97. row_pointers[y][x++] = r;
  98. row_pointers[y][x++] = g;
  99. row_pointers[y][x++] = b;
  100. // Odd numbers of columns quit here
  101. if(x < endpoint)
  102. {
  103. r = ((y2 + codec->vtor[v]) >> 16);
  104. g = ((y2 + codec->utog[u] + codec->vtog[v]) >> 16);
  105. b = ((y2 + codec->utob[u]) >> 16);
  106. if(r < 0) r = 0;
  107. if(g < 0) g = 0;
  108. if(b < 0) b = 0;
  109. if(r > 255) r = 255;
  110. if(g > 255) g = 255;
  111. if(b > 255) b = 255;
  112. row_pointers[y][x++] = r;
  113. row_pointers[y][x++] = g;
  114. row_pointers[y][x++] = b;
  115. }
  116. }
  117. }
  118. return result;
  119. }
  120. int quicktime_encode_yuv2(quicktime_t *file, unsigned char **row_pointers, int track)
  121. {
  122. long offset = quicktime_position(file);
  123. quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  124. quicktime_yuv2_codec_t *codec = &(vtrack->codecs.yuv2_codec);
  125. int result = 0;
  126. int width = vtrack->track->tkhd.track_width;
  127. int height = vtrack->track->tkhd.track_height;
  128. long bytes = height * codec->bytes_per_line;
  129. unsigned char *buffer = vtrack->codecs.yuv2_codec.work_buffer;
  130. unsigned char *row_pointer;
  131. int x, y;
  132. int y1, u, y2, v;
  133. int r, g, b;
  134. int endpoint = width * 3;
  135. for(y = 0; y < height; y++)
  136. {
  137. row_pointer = buffer + y * codec->bytes_per_line;
  138. for(x = 0; x < endpoint; )
  139. {
  140. r = row_pointers[y][x++];
  141. g = row_pointers[y][x++];
  142. b = row_pointers[y][x++];
  143. y1 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);
  144. u  = (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);
  145. v  = (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);
  146. if(x < endpoint)
  147. {
  148. r = row_pointers[y][x++];
  149. g = row_pointers[y][x++];
  150. b = row_pointers[y][x++];
  151. }
  152. y2 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);
  153. u += (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);
  154. v += (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);
  155. y1 /= 0x10000;
  156. y2 /= 0x10000;
  157. u /= 0x20000;
  158. v /= 0x20000;
  159. if(y1 > 255) y1 = 255;
  160. if(y2 > 255) y2 = 255;
  161. if(u > 127) u = 127;
  162. if(v > 127) v = 127;
  163. if(y1 < 0) y1 = 0;
  164. if(y2 < 0) y2 = 0;
  165. if(u < -128) u = -128;
  166. if(v < -128) v = -128;
  167. *row_pointer++ = y1;
  168. *row_pointer++ = u;
  169. *row_pointer++ = y2;
  170. *row_pointer++ = v;
  171. }
  172. }
  173. result = quicktime_write_data(file, buffer, bytes);
  174. if(result) result = 0; else result = 1;
  175. quicktime_update_tables(file->vtracks[track].track,
  176. offset,
  177. file->vtracks[track].current_chunk,
  178. file->vtracks[track].current_position,
  179. 1,
  180. bytes);
  181. file->vtracks[track].current_chunk++;
  182. return result;
  183. }