Mercurial > libavcodec.hg
comparison imgconvert.c @ 1202:8b49a7ee4e4e libavcodec
YUV formats/gray formats are correctly defined - added format loss information - preliminary JPEG YUV formats support
author | bellard |
---|---|
date | Sun, 20 Apr 2003 16:18:44 +0000 |
parents | 6b566c5d02e4 |
children | 80c73b9b0ba2 |
comparison
equal
deleted
inserted
replaced
1201:e0fc95a6eb4e | 1202:8b49a7ee4e4e |
---|---|
32 | 32 |
33 #ifdef HAVE_MMX | 33 #ifdef HAVE_MMX |
34 #include "i386/mmx.h" | 34 #include "i386/mmx.h" |
35 #endif | 35 #endif |
36 | 36 |
37 #define FF_COLOR_RGB 0 /* RGB color space */ | |
38 #define FF_COLOR_GRAY 1 /* gray color space */ | |
39 #define FF_COLOR_YUV 2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ | |
40 #define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ | |
41 | |
37 typedef struct PixFmtInfo { | 42 typedef struct PixFmtInfo { |
38 const char *name; | 43 const char *name; |
39 uint8_t nb_components; /* number of components in AVPicture array */ | 44 uint8_t nb_components; /* number of components in AVPicture array */ |
40 uint8_t is_yuv : 1; /* true if YUV instead of RGB color space */ | 45 uint8_t color_type; /* color type (see FF_COLOR_xxx constants) */ |
41 uint8_t is_packed : 1; /* true if multiple components in same word */ | 46 uint8_t is_packed : 1; /* true if multiple components in same word */ |
42 uint8_t is_paletted : 1; /* true if paletted */ | 47 uint8_t is_paletted : 1; /* true if paletted */ |
43 uint8_t is_alpha : 1; /* true if alpha can be specified */ | 48 uint8_t is_alpha : 1; /* true if alpha can be specified */ |
44 uint8_t is_gray : 1; /* true if gray or monochrome format */ | |
45 uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */ | 49 uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */ |
46 uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */ | 50 uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */ |
51 uint8_t depth; /* bit depth of the color components */ | |
47 } PixFmtInfo; | 52 } PixFmtInfo; |
48 | 53 |
49 /* this table gives more information about formats */ | 54 /* this table gives more information about formats */ |
50 static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { | 55 static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { |
51 /* YUV formats */ | 56 /* YUV formats */ |
52 [PIX_FMT_YUV420P] = { | 57 [PIX_FMT_YUV420P] = { |
53 .name = "yuv420p", | 58 .name = "yuv420p", |
54 .nb_components = 3, .is_yuv = 1, | 59 .nb_components = 3, |
60 .color_type = FF_COLOR_YUV, | |
61 .depth = 8, | |
55 .x_chroma_shift = 1, .y_chroma_shift = 1, | 62 .x_chroma_shift = 1, .y_chroma_shift = 1, |
56 }, | 63 }, |
57 [PIX_FMT_YUV422P] = { | 64 [PIX_FMT_YUV422P] = { |
58 .name = "yuv422p", | 65 .name = "yuv422p", |
59 .nb_components = 3, .is_yuv = 1, | 66 .nb_components = 3, |
67 .color_type = FF_COLOR_YUV, | |
68 .depth = 8, | |
60 .x_chroma_shift = 1, .y_chroma_shift = 0, | 69 .x_chroma_shift = 1, .y_chroma_shift = 0, |
61 }, | 70 }, |
62 [PIX_FMT_YUV444P] = { | 71 [PIX_FMT_YUV444P] = { |
63 .name = "yuv444p", | 72 .name = "yuv444p", |
64 .nb_components = 3, .is_yuv = 1, | 73 .nb_components = 3, |
74 .color_type = FF_COLOR_YUV, | |
75 .depth = 8, | |
65 .x_chroma_shift = 0, .y_chroma_shift = 0, | 76 .x_chroma_shift = 0, .y_chroma_shift = 0, |
66 }, | 77 }, |
67 [PIX_FMT_YUV422] = { | 78 [PIX_FMT_YUV422] = { |
68 .name = "yuv422", | 79 .name = "yuv422", |
69 .nb_components = 1, .is_yuv = 1, .is_packed = 1, | 80 .nb_components = 1, .is_packed = 1, |
81 .color_type = FF_COLOR_YUV, | |
82 .depth = 8, | |
70 .x_chroma_shift = 1, .y_chroma_shift = 0, | 83 .x_chroma_shift = 1, .y_chroma_shift = 0, |
71 }, | 84 }, |
72 [PIX_FMT_YUV410P] = { | 85 [PIX_FMT_YUV410P] = { |
73 .name = "yuv410p", | 86 .name = "yuv410p", |
74 .nb_components = 3, .is_yuv = 1, | 87 .nb_components = 3, |
88 .color_type = FF_COLOR_YUV, | |
89 .depth = 8, | |
75 .x_chroma_shift = 2, .y_chroma_shift = 2, | 90 .x_chroma_shift = 2, .y_chroma_shift = 2, |
76 }, | 91 }, |
77 [PIX_FMT_YUV411P] = { | 92 [PIX_FMT_YUV411P] = { |
78 .name = "yuv411p", | 93 .name = "yuv411p", |
79 .nb_components = 3, .is_yuv = 1, | 94 .nb_components = 3, |
95 .color_type = FF_COLOR_YUV, | |
96 .depth = 8, | |
80 .x_chroma_shift = 2, .y_chroma_shift = 0, | 97 .x_chroma_shift = 2, .y_chroma_shift = 0, |
98 }, | |
99 | |
100 /* JPEG YUV */ | |
101 [PIX_FMT_YUVJ420P] = { | |
102 .name = "yuvj420p", | |
103 .nb_components = 3, | |
104 .color_type = FF_COLOR_YUV_JPEG, | |
105 .depth = 8, | |
106 .x_chroma_shift = 1, .y_chroma_shift = 1, | |
107 }, | |
108 [PIX_FMT_YUVJ422P] = { | |
109 .name = "yuvj422p", | |
110 .nb_components = 3, | |
111 .color_type = FF_COLOR_YUV_JPEG, | |
112 .depth = 8, | |
113 .x_chroma_shift = 1, .y_chroma_shift = 0, | |
114 }, | |
115 [PIX_FMT_YUVJ444P] = { | |
116 .name = "yuvj444p", | |
117 .nb_components = 3, | |
118 .color_type = FF_COLOR_YUV_JPEG, | |
119 .depth = 8, | |
120 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
81 }, | 121 }, |
82 | 122 |
83 /* RGB formats */ | 123 /* RGB formats */ |
84 [PIX_FMT_RGB24] = { | 124 [PIX_FMT_RGB24] = { |
85 .name = "rgb24", | 125 .name = "rgb24", |
86 .nb_components = 1, .is_packed = 1, | 126 .nb_components = 1, .is_packed = 1, |
127 .color_type = FF_COLOR_RGB, | |
128 .depth = 8, | |
87 }, | 129 }, |
88 [PIX_FMT_BGR24] = { | 130 [PIX_FMT_BGR24] = { |
89 .name = "bgr24", | 131 .name = "bgr24", |
90 .nb_components = 1, .is_packed = 1, | 132 .nb_components = 1, .is_packed = 1, |
133 .color_type = FF_COLOR_RGB, | |
134 .depth = 8, | |
91 }, | 135 }, |
92 [PIX_FMT_RGBA32] = { | 136 [PIX_FMT_RGBA32] = { |
93 .name = "rgba32", | 137 .name = "rgba32", |
94 .nb_components = 1, .is_packed = 1, .is_alpha = 1, | 138 .nb_components = 1, .is_packed = 1, .is_alpha = 1, |
139 .color_type = FF_COLOR_RGB, | |
140 .depth = 8, | |
95 }, | 141 }, |
96 [PIX_FMT_RGB565] = { | 142 [PIX_FMT_RGB565] = { |
97 .name = "rgb565", | 143 .name = "rgb565", |
98 .nb_components = 1, .is_packed = 1, | 144 .nb_components = 1, .is_packed = 1, |
145 .color_type = FF_COLOR_RGB, | |
146 .depth = 5, | |
99 }, | 147 }, |
100 [PIX_FMT_RGB555] = { | 148 [PIX_FMT_RGB555] = { |
101 .name = "rgb555", | 149 .name = "rgb555", |
102 .nb_components = 1, .is_packed = 1, .is_alpha = 1, | 150 .nb_components = 1, .is_packed = 1, .is_alpha = 1, |
151 .color_type = FF_COLOR_RGB, | |
152 .depth = 5, | |
103 }, | 153 }, |
104 | 154 |
105 /* gray / mono formats */ | 155 /* gray / mono formats */ |
106 [PIX_FMT_GRAY8] = { | 156 [PIX_FMT_GRAY8] = { |
107 .name = "gray", | 157 .name = "gray", |
108 .nb_components = 1, .is_gray = 1, | 158 .nb_components = 1, |
159 .color_type = FF_COLOR_GRAY, | |
160 .depth = 8, | |
109 }, | 161 }, |
110 [PIX_FMT_MONOWHITE] = { | 162 [PIX_FMT_MONOWHITE] = { |
111 .name = "monow", | 163 .name = "monow", |
112 .nb_components = 1, .is_packed = 1, .is_gray = 1, | 164 .nb_components = 1, |
165 .color_type = FF_COLOR_GRAY, | |
166 .depth = 1, | |
113 }, | 167 }, |
114 [PIX_FMT_MONOBLACK] = { | 168 [PIX_FMT_MONOBLACK] = { |
115 .name = "monob", | 169 .name = "monob", |
116 .nb_components = 1, .is_packed = 1, .is_gray = 1, | 170 .nb_components = 1, |
171 .color_type = FF_COLOR_GRAY, | |
172 .depth = 1, | |
117 }, | 173 }, |
118 | 174 |
119 /* paletted formats */ | 175 /* paletted formats */ |
120 [PIX_FMT_PAL8] = { | 176 [PIX_FMT_PAL8] = { |
121 .name = "pal8", | 177 .name = "pal8", |
122 .nb_components = 1, .is_packed = 1, .is_alpha = 1, .is_paletted = 1, | 178 .nb_components = 1, .is_packed = 1, .is_alpha = 1, .is_paletted = 1, |
179 .color_type = FF_COLOR_RGB, | |
180 .depth = 8, | |
123 }, | 181 }, |
124 }; | 182 }; |
125 | 183 |
126 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift) | 184 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift) |
127 { | 185 { |
128 if (pix_fmt_info[pix_fmt].is_yuv) { | 186 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift; |
129 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift; | 187 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift; |
130 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift; | |
131 } else { | |
132 *h_shift=0; | |
133 *v_shift=0; | |
134 } | |
135 } | 188 } |
136 | 189 |
137 const char *avcodec_get_pix_fmt_name(int pix_fmt) | 190 const char *avcodec_get_pix_fmt_name(int pix_fmt) |
138 { | 191 { |
139 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) | 192 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) |
222 { | 275 { |
223 AVPicture dummy_pict; | 276 AVPicture dummy_pict; |
224 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); | 277 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); |
225 } | 278 } |
226 | 279 |
280 /** | |
281 * compute the loss when converting from a pixel format to another | |
282 */ | |
283 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, | |
284 int has_alpha) | |
285 { | |
286 const PixFmtInfo *pf, *ps; | |
287 int loss; | |
288 | |
289 ps = &pix_fmt_info[src_pix_fmt]; | |
290 pf = &pix_fmt_info[dst_pix_fmt]; | |
291 | |
292 /* compute loss */ | |
293 loss = 0; | |
294 pf = &pix_fmt_info[dst_pix_fmt]; | |
295 if (pf->depth < ps->depth) | |
296 loss |= FF_LOSS_DEPTH; | |
297 if (pf->x_chroma_shift >= ps->x_chroma_shift || | |
298 pf->y_chroma_shift >= ps->y_chroma_shift) | |
299 loss |= FF_LOSS_RESOLUTION; | |
300 switch(pf->color_type) { | |
301 case FF_COLOR_RGB: | |
302 if (ps->color_type != FF_COLOR_RGB && | |
303 ps->color_type != FF_COLOR_GRAY) | |
304 loss |= FF_LOSS_COLORSPACE; | |
305 break; | |
306 case FF_COLOR_GRAY: | |
307 if (ps->color_type != FF_COLOR_GRAY) | |
308 loss |= FF_LOSS_COLORSPACE; | |
309 break; | |
310 case FF_COLOR_YUV: | |
311 if (ps->color_type != FF_COLOR_YUV) | |
312 loss |= FF_LOSS_COLORSPACE; | |
313 break; | |
314 case FF_COLOR_YUV_JPEG: | |
315 if (ps->color_type != FF_COLOR_YUV_JPEG && | |
316 ps->color_type != FF_COLOR_YUV) | |
317 loss |= FF_LOSS_COLORSPACE; | |
318 break; | |
319 default: | |
320 /* fail safe test */ | |
321 if (ps->color_type != pf->color_type) | |
322 loss |= FF_LOSS_COLORSPACE; | |
323 break; | |
324 } | |
325 if (pf->color_type == FF_COLOR_GRAY && | |
326 ps->color_type != FF_COLOR_GRAY) | |
327 loss |= FF_LOSS_CHROMA; | |
328 if (!pf->is_alpha && (ps->is_alpha && has_alpha)) | |
329 loss |= FF_LOSS_ALPHA; | |
330 if (pf->is_paletted && (!ps->is_paletted && ps->color_type != FF_COLOR_GRAY)) | |
331 loss |= FF_LOSS_COLORQUANT; | |
332 return loss; | |
333 } | |
334 | |
335 static int avg_bits_per_pixel(int pix_fmt) | |
336 { | |
337 int bits; | |
338 const PixFmtInfo *pf; | |
339 | |
340 pf = &pix_fmt_info[pix_fmt]; | |
341 if (pf->is_packed) { | |
342 switch(pix_fmt) { | |
343 case PIX_FMT_RGB24: | |
344 case PIX_FMT_BGR24: | |
345 bits = 24; | |
346 break; | |
347 case PIX_FMT_RGBA32: | |
348 bits = 32; | |
349 break; | |
350 case PIX_FMT_RGB565: | |
351 case PIX_FMT_RGB555: | |
352 bits = 16; | |
353 break; | |
354 case PIX_FMT_PAL8: | |
355 bits = 8; | |
356 break; | |
357 default: | |
358 bits = 32; | |
359 break; | |
360 } | |
361 } else { | |
362 bits = pf->depth; | |
363 bits += (2 * pf->depth >> | |
364 (pf->x_chroma_shift + pf->x_chroma_shift)); | |
365 } | |
366 return bits; | |
367 } | |
368 | |
369 static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, | |
370 int src_pix_fmt, | |
371 int has_alpha, | |
372 int loss_mask) | |
373 { | |
374 int dist, i, loss, min_dist, dst_pix_fmt; | |
375 | |
376 /* find exact color match with smallest size */ | |
377 dst_pix_fmt = -1; | |
378 min_dist = 0x7fffffff; | |
379 for(i = 0;i < PIX_FMT_NB; i++) { | |
380 if (pix_fmt_mask & (1 << i)) { | |
381 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask; | |
382 if (loss == 0) { | |
383 dist = avg_bits_per_pixel(i); | |
384 if (dist < min_dist) { | |
385 min_dist = dist; | |
386 dst_pix_fmt = i; | |
387 } | |
388 } | |
389 } | |
390 } | |
391 return dst_pix_fmt; | |
392 } | |
393 | |
394 /** | |
395 * find best pixel format to convert to. Return -1 if none found | |
396 */ | |
397 int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, | |
398 int has_alpha, int *loss_ptr) | |
399 { | |
400 int dst_pix_fmt, loss_mask, i; | |
401 static const int loss_mask_order[] = { | |
402 ~0, /* no loss first */ | |
403 ~FF_LOSS_ALPHA, | |
404 ~FF_LOSS_RESOLUTION, | |
405 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION), | |
406 ~FF_LOSS_COLORQUANT, | |
407 ~FF_LOSS_DEPTH, | |
408 0, | |
409 }; | |
410 | |
411 /* try with successive loss */ | |
412 i = 0; | |
413 for(;;) { | |
414 loss_mask = loss_mask_order[i++]; | |
415 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, | |
416 has_alpha, loss_mask); | |
417 if (dst_pix_fmt >= 0) | |
418 goto found; | |
419 if (loss_mask == 0) | |
420 break; | |
421 } | |
422 return -1; | |
423 found: | |
424 if (loss_ptr) | |
425 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); | |
426 return dst_pix_fmt; | |
427 } | |
428 | |
227 | 429 |
228 /* XXX: totally non optimized */ | 430 /* XXX: totally non optimized */ |
229 | 431 |
230 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src, | 432 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src, |
231 int width, int height) | 433 int width, int height) |
261 | 463 |
262 #define SCALEBITS 8 | 464 #define SCALEBITS 8 |
263 #define ONE_HALF (1 << (SCALEBITS - 1)) | 465 #define ONE_HALF (1 << (SCALEBITS - 1)) |
264 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5)) | 466 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5)) |
265 | 467 |
468 #define SCALE_BITS 10 | |
469 | |
470 #define C_Y (76309 >> (16 - SCALE_BITS)) | |
471 #define C_RV (117504 >> (16 - SCALE_BITS)) | |
472 #define C_BU (138453 >> (16 - SCALE_BITS)) | |
473 #define C_GU (13954 >> (16 - SCALE_BITS)) | |
474 #define C_GV (34903 >> (16 - SCALE_BITS)) | |
475 | |
476 #define YUV_TO_RGB2(r, g, b, y1)\ | |
477 {\ | |
478 y = (y1 - 16) * C_Y;\ | |
479 r = cm[(y + r_add) >> SCALE_BITS];\ | |
480 g = cm[(y + g_add) >> SCALE_BITS];\ | |
481 b = cm[(y + b_add) >> SCALE_BITS];\ | |
482 } | |
483 | |
484 /* XXX: use a table ? */ | |
485 #define CCIR_TO_GRAY(y)\ | |
486 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS] | |
487 | |
488 #define GRAY_TO_CCIR(y)\ | |
489 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) | |
490 | |
491 #define RGB_TO_Y(r, g, b) \ | |
492 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \ | |
493 FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS) | |
494 | |
495 #define RGB4_TO_U(r1, g1, b1)\ | |
496 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ | |
497 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) | |
498 | |
499 #define RGB4_TO_V(r1, g1, b1)\ | |
500 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ | |
501 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) | |
502 | |
503 #define RGB_TO_Y_CCIR(r, g, b) \ | |
504 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ | |
505 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) | |
506 | |
507 #define RGB4_TO_U_CCIR(r1, g1, b1)\ | |
508 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ | |
509 FIX(0.50000*224.0/255.0) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) | |
510 | |
511 #define RGB4_TO_V_CCIR(r1, g1, b1)\ | |
512 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ | |
513 FIX(0.08131*224.0/255.0) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) | |
514 | |
515 /* convert from CCIR luma (16 <= Y <= 235) to full scale gray (0 <= Y <= 255) */ | |
516 static void luma_ccir_to_gray(uint8_t *dst, int dst_wrap, | |
517 uint8_t *src, int src_wrap, | |
518 int width, int height) | |
519 { | |
520 int n; | |
521 const uint8_t *s; | |
522 uint8_t *d; | |
523 uint8_t *cm = cropTbl + MAX_NEG_CROP; | |
524 | |
525 for(;height > 0; height--) { | |
526 s = src; | |
527 d = dst; | |
528 n = width; | |
529 while (n >= 4) { | |
530 d[0] = CCIR_TO_GRAY(s[0]); | |
531 d[1] = CCIR_TO_GRAY(s[1]); | |
532 d[2] = CCIR_TO_GRAY(s[2]); | |
533 d[3] = CCIR_TO_GRAY(s[3]); | |
534 d += 4; | |
535 s += 4; | |
536 n -= 4; | |
537 } | |
538 while (n > 0) { | |
539 d[0] = CCIR_TO_GRAY(s[0]); | |
540 d++; | |
541 s++; | |
542 n--; | |
543 } | |
544 dst += dst_wrap; | |
545 src += src_wrap; | |
546 } | |
547 } | |
548 | |
549 /* convert from full scale gray (0 <= Y <= 255) to CCIR luma (16 <= Y <= 235) */ | |
550 static void gray_to_luma_ccir(uint8_t *dst, int dst_wrap, | |
551 uint8_t *src, int src_wrap, | |
552 int width, int height) | |
553 { | |
554 int n; | |
555 const uint8_t *s; | |
556 uint8_t *d; | |
557 | |
558 for(;height > 0; height--) { | |
559 s = src; | |
560 d = dst; | |
561 n = width; | |
562 while (n >= 4) { | |
563 d[0] = GRAY_TO_CCIR(s[0]); | |
564 d[1] = GRAY_TO_CCIR(s[1]); | |
565 d[2] = GRAY_TO_CCIR(s[2]); | |
566 d[3] = GRAY_TO_CCIR(s[3]); | |
567 d += 4; | |
568 s += 4; | |
569 n -= 4; | |
570 } | |
571 while (n > 0) { | |
572 d[0] = GRAY_TO_CCIR(s[0]); | |
573 d++; | |
574 s++; | |
575 n--; | |
576 } | |
577 dst += dst_wrap; | |
578 src += src_wrap; | |
579 } | |
580 } | |
581 | |
266 /* XXX: use generic filter ? */ | 582 /* XXX: use generic filter ? */ |
267 /* 1x2 -> 1x1 */ | 583 /* 1x2 -> 1x1 */ |
268 static void shrink2(uint8_t *dst, int dst_wrap, | 584 static void shrink2(uint8_t *dst, int dst_wrap, |
269 uint8_t *src, int src_wrap, | 585 uint8_t *src, int src_wrap, |
270 int width, int height) | 586 int width, int height) |
390 for(;height > 0; height--) { | 706 for(;height > 0; height--) { |
391 memcpy(dst, src, width); | 707 memcpy(dst, src, width); |
392 dst += dst_wrap; | 708 dst += dst_wrap; |
393 src += src_wrap; | 709 src += src_wrap; |
394 } | 710 } |
395 } | |
396 | |
397 #define SCALE_BITS 10 | |
398 | |
399 #define C_Y (76309 >> (16 - SCALE_BITS)) | |
400 #define C_RV (117504 >> (16 - SCALE_BITS)) | |
401 #define C_BU (138453 >> (16 - SCALE_BITS)) | |
402 #define C_GU (13954 >> (16 - SCALE_BITS)) | |
403 #define C_GV (34903 >> (16 - SCALE_BITS)) | |
404 | |
405 #define YUV_TO_RGB2(r, g, b, y1)\ | |
406 {\ | |
407 y = (y1 - 16) * C_Y;\ | |
408 r = cm[(y + r_add) >> SCALE_BITS];\ | |
409 g = cm[(y + g_add) >> SCALE_BITS];\ | |
410 b = cm[(y + b_add) >> SCALE_BITS];\ | |
411 } | 711 } |
412 | 712 |
413 /* XXX: no chroma interpolating is done */ | 713 /* XXX: no chroma interpolating is done */ |
414 #define RGB_FUNCTIONS(rgb_name) \ | 714 #define RGB_FUNCTIONS(rgb_name) \ |
415 \ | 715 \ |
605 for(x=0;x<width;x+=2) { \ | 905 for(x=0;x<width;x+=2) { \ |
606 RGB_IN(r, g, b, p); \ | 906 RGB_IN(r, g, b, p); \ |
607 r1 = r; \ | 907 r1 = r; \ |
608 g1 = g; \ | 908 g1 = g; \ |
609 b1 = b; \ | 909 b1 = b; \ |
610 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 910 lum[0] = RGB_TO_Y_CCIR(r, g, b); \ |
611 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | 911 \ |
612 RGB_IN(r, g, b, p + BPP); \ | 912 RGB_IN(r, g, b, p + BPP); \ |
613 r1 += r; \ | 913 r1 += r; \ |
614 g1 += g; \ | 914 g1 += g; \ |
615 b1 += b; \ | 915 b1 += b; \ |
616 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 916 lum[1] = RGB_TO_Y_CCIR(r, g, b); \ |
617 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | |
618 p += wrap3; \ | 917 p += wrap3; \ |
619 lum += wrap; \ | 918 lum += wrap; \ |
620 \ | 919 \ |
621 RGB_IN(r, g, b, p); \ | 920 RGB_IN(r, g, b, p); \ |
622 r1 += r; \ | 921 r1 += r; \ |
623 g1 += g; \ | 922 g1 += g; \ |
624 b1 += b; \ | 923 b1 += b; \ |
625 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 924 lum[0] = RGB_TO_Y_CCIR(r, g, b); \ |
626 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | 925 \ |
627 \ | |
628 RGB_IN(r, g, b, p + BPP); \ | 926 RGB_IN(r, g, b, p + BPP); \ |
629 r1 += r; \ | 927 r1 += r; \ |
630 g1 += g; \ | 928 g1 += g; \ |
631 b1 += b; \ | 929 b1 += b; \ |
632 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 930 lum[1] = RGB_TO_Y_CCIR(r, g, b); \ |
633 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | 931 \ |
634 \ | 932 cb[0] = RGB4_TO_U_CCIR(r1, g1, b1); \ |
635 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ | 933 cr[0] = RGB4_TO_V_CCIR(r1, g1, b1); \ |
636 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> \ | |
637 (SCALEBITS + 2)) + 128; \ | |
638 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ | |
639 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> \ | |
640 (SCALEBITS + 2)) + 128; \ | |
641 \ | 934 \ |
642 cb++; \ | 935 cb++; \ |
643 cr++; \ | 936 cr++; \ |
644 p += -wrap3 + 2 * BPP; \ | 937 p += -wrap3 + 2 * BPP; \ |
645 lum += -wrap + 2; \ | 938 lum += -wrap + 2; \ |
666 dst_wrap = dst->linesize[0] - width; \ | 959 dst_wrap = dst->linesize[0] - width; \ |
667 \ | 960 \ |
668 for(y=0;y<height;y++) { \ | 961 for(y=0;y<height;y++) { \ |
669 for(x=0;x<width;x++) { \ | 962 for(x=0;x<width;x++) { \ |
670 RGB_IN(r, g, b, p); \ | 963 RGB_IN(r, g, b, p); \ |
671 q[0] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 964 q[0] = RGB_TO_Y(r, g, b); \ |
672 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | |
673 q++; \ | 965 q++; \ |
674 p += BPP; \ | 966 p += BPP; \ |
675 } \ | 967 } \ |
676 p += src_wrap; \ | 968 p += src_wrap; \ |
677 q += dst_wrap; \ | 969 q += dst_wrap; \ |
1315 /* same format: just copy */ | 1607 /* same format: just copy */ |
1316 for(i = 0; i < dst_pix->nb_components; i++) { | 1608 for(i = 0; i < dst_pix->nb_components; i++) { |
1317 int w, h; | 1609 int w, h; |
1318 w = dst_width; | 1610 w = dst_width; |
1319 h = dst_height; | 1611 h = dst_height; |
1320 if (dst_pix->is_yuv && (i == 1 || i == 2)) { | 1612 if ((dst_pix->color_type == FF_COLOR_YUV || |
1613 dst_pix->color_type == FF_COLOR_YUV_JPEG) && | |
1614 (i == 1 || i == 2)) { | |
1321 w >>= dst_pix->x_chroma_shift; | 1615 w >>= dst_pix->x_chroma_shift; |
1322 h >>= dst_pix->y_chroma_shift; | 1616 h >>= dst_pix->y_chroma_shift; |
1323 } | 1617 } |
1324 img_copy(dst->data[i], dst->linesize[i], | 1618 img_copy(dst->data[i], dst->linesize[i], |
1325 src->data[i], src->linesize[i], | 1619 src->data[i], src->linesize[i], |
1334 ce->convert(dst, src, dst_width, dst_height); | 1628 ce->convert(dst, src, dst_width, dst_height); |
1335 return 0; | 1629 return 0; |
1336 } | 1630 } |
1337 | 1631 |
1338 /* gray to YUV */ | 1632 /* gray to YUV */ |
1339 if (dst_pix->is_yuv && src_pix_fmt == PIX_FMT_GRAY8) { | 1633 if ((dst_pix->color_type == FF_COLOR_YUV || |
1634 dst_pix->color_type == FF_COLOR_YUV_JPEG) && | |
1635 src_pix_fmt == PIX_FMT_GRAY8) { | |
1340 int w, h, y; | 1636 int w, h, y; |
1341 uint8_t *d; | 1637 uint8_t *d; |
1342 | 1638 |
1343 img_copy(dst->data[0], dst->linesize[0], | 1639 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) { |
1344 src->data[0], src->linesize[0], | 1640 img_copy(dst->data[0], dst->linesize[0], |
1345 dst_width, dst_height); | 1641 src->data[0], src->linesize[0], |
1642 dst_width, dst_height); | |
1643 } else { | |
1644 gray_to_luma_ccir(dst->data[0], dst->linesize[0], | |
1645 src->data[0], src->linesize[0], | |
1646 dst_width, dst_height); | |
1647 } | |
1346 /* fill U and V with 128 */ | 1648 /* fill U and V with 128 */ |
1347 w = dst_width; | 1649 w = dst_width; |
1348 h = dst_height; | 1650 h = dst_height; |
1349 w >>= dst_pix->x_chroma_shift; | 1651 w >>= dst_pix->x_chroma_shift; |
1350 h >>= dst_pix->y_chroma_shift; | 1652 h >>= dst_pix->y_chroma_shift; |
1357 } | 1659 } |
1358 return 0; | 1660 return 0; |
1359 } | 1661 } |
1360 | 1662 |
1361 /* YUV to gray */ | 1663 /* YUV to gray */ |
1362 if (src_pix->is_yuv && dst_pix_fmt == PIX_FMT_GRAY8) { | 1664 if ((src_pix->color_type == FF_COLOR_YUV || |
1363 img_copy(dst->data[0], dst->linesize[0], | 1665 src_pix->color_type == FF_COLOR_YUV_JPEG) && |
1364 src->data[0], src->linesize[0], | 1666 dst_pix_fmt == PIX_FMT_GRAY8) { |
1365 dst_width, dst_height); | 1667 if (src_pix->color_type == FF_COLOR_YUV_JPEG) { |
1668 img_copy(dst->data[0], dst->linesize[0], | |
1669 src->data[0], src->linesize[0], | |
1670 dst_width, dst_height); | |
1671 } else { | |
1672 luma_ccir_to_gray(dst->data[0], dst->linesize[0], | |
1673 src->data[0], src->linesize[0], | |
1674 dst_width, dst_height); | |
1675 } | |
1366 return 0; | 1676 return 0; |
1367 } | 1677 } |
1368 | 1678 |
1369 /* YUV to YUV */ | 1679 /* YUV to YUV */ |
1370 if (dst_pix->is_yuv && src_pix->is_yuv) { | 1680 if (dst_pix->color_type == FF_COLOR_YUV && |
1681 dst_pix->color_type == src_pix->color_type) { | |
1371 int x_shift, y_shift, w, h; | 1682 int x_shift, y_shift, w, h; |
1372 void (*resize_func)(uint8_t *dst, int dst_wrap, | 1683 void (*resize_func)(uint8_t *dst, int dst_wrap, |
1373 uint8_t *src, int src_wrap, | 1684 uint8_t *src, int src_wrap, |
1374 int width, int height); | 1685 int width, int height); |
1375 | 1686 |