1/* 2 * copyright (c) Sebastien Bechet <s.bechet@av7.net> 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include <errno.h> 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25 26#define SCALEBITS 8 27#define ONE_HALF (1 << (SCALEBITS - 1)) 28#define FIX(x) ((int) ((x) * (1 << SCALEBITS) + 0.5)) 29 30#define err_if(expr) do { \ 31 if (expr) { \ 32 fprintf(stderr, "%s\n", strerror(errno)); \ 33 exit(1); \ 34 } \ 35} while (0) 36 37static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb, 38 unsigned char *cr, const unsigned char *src, 39 int width, int height) 40{ 41 int wrap, wrap3, x, y; 42 int r, g, b, r1, g1, b1; 43 const unsigned char *p; 44 45 wrap = width; 46 wrap3 = width * 3; 47 p = src; 48 for (y = 0; y < height; y += 2) { 49 for (x = 0; x < width; x += 2) { 50 r = p[0]; 51 g = p[1]; 52 b = p[2]; 53 r1 = r; 54 g1 = g; 55 b1 = b; 56 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 57 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; 58 r = p[3]; 59 g = p[4]; 60 b = p[5]; 61 r1 += r; 62 g1 += g; 63 b1 += b; 64 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 65 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; 66 p += wrap3; 67 lum += wrap; 68 69 r = p[0]; 70 g = p[1]; 71 b = p[2]; 72 r1 += r; 73 g1 += g; 74 b1 += b; 75 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 76 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; 77 r = p[3]; 78 g = p[4]; 79 b = p[5]; 80 r1 += r; 81 g1 += g; 82 b1 += b; 83 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 84 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; 85 86 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 87 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128; 88 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 89 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128; 90 91 cb++; 92 cr++; 93 p += -wrap3 + 2 * 3; 94 lum += -wrap + 2; 95 } 96 p += wrap3; 97 lum += wrap; 98 } 99} 100 101/* cif format */ 102#define DEFAULT_WIDTH 352 103#define DEFAULT_HEIGHT 288 104#define DEFAULT_NB_PICT 50 105 106static void pgmyuv_save(const char *filename, int w, int h, 107 const unsigned char *rgb_tab) 108{ 109 FILE *f; 110 int i, h2, w2; 111 unsigned char *cb, *cr; 112 unsigned char *lum_tab, *cb_tab, *cr_tab; 113 114 lum_tab = malloc(w * h); 115 cb_tab = malloc(w * h / 4); 116 cr_tab = malloc(w * h / 4); 117 118 rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h); 119 120 if (filename) { 121 f = fopen(filename, "wb"); 122 fprintf(f, "P5\n%d %d\n%d\n", w, h * 3 / 2, 255); 123 } else { 124 f = stdout; 125 } 126 127 err_if(fwrite(lum_tab, 1, w * h, f) != w * h); 128 h2 = h / 2; 129 w2 = w / 2; 130 cb = cb_tab; 131 cr = cr_tab; 132 133 if (filename) { 134 for (i = 0; i < h2; i++) { 135 err_if(fwrite(cb, 1, w2, f) != w2); 136 err_if(fwrite(cr, 1, w2, f) != w2); 137 cb += w2; 138 cr += w2; 139 } 140 fclose(f); 141 } else { 142 for (i = 0; i < h2; i++) { 143 err_if(fwrite(cb, 1, w2, f) != w2); 144 cb += w2; 145 } 146 for (i = 0; i < h2; i++) { 147 err_if(fwrite(cr, 1, w2, f) != w2); 148 cr += w2; 149 } 150 } 151 152 free(lum_tab); 153 free(cb_tab); 154 free(cr_tab); 155} 156 157static unsigned char *rgb_tab; 158static int width, height, wrap; 159 160static void put_pixel(int x, int y, int r, int g, int b) 161{ 162 unsigned char *p; 163 164 if (x < 0 || x >= width || 165 y < 0 || y >= height) 166 return; 167 168 p = rgb_tab + y * wrap + x * 3; 169 p[0] = r; 170 p[1] = g; 171 p[2] = b; 172} 173