usage:
unsigned char rgb[1920*1080*3];
// covert yuv420sp after resizing to bmp
vuy420sp_to_rgb(buf, buf+offsetH*offsetV, rgb, offsetH, offsetV);
// save as bmp file
bmp_write(rgb, offsetH, offsetV, "/tmp/img.bmp");
#ifndef bmp_h #define bmp_h #include <stdio.h> #include <stdlib.h> #include <string.h> static void vuy420sp_to_rgb(const unsigned char* y, const unsigned char* uv, unsigned char* rgb, unsigned int width, unsigned int height) { unsigned int halfwidth = width >> 1; int yy, uu, vv, ug_plus_vg, ub, vr; int r, g, b; unsigned int i, j; for (i = 0; i < height; ++i) { for (j = 0; j < halfwidth; ++j) { yy = y[0] << 8; vv = *(uv++) - 128; uu = *(uv++) - 128; ug_plus_vg = uu * 88 + vv * 183; ub = uu * 454; vr = vv * 359; r = (yy + vr) >> 8; g = (yy - ug_plus_vg) >> 8; b = (yy + ub) >> 8; rgb[0] = r < 0 ? 0 : (r > 255 ? 255 : (unsigned char)r); rgb[1] = g < 0 ? 0 : (g > 255 ? 255 : (unsigned char)g); rgb[2] = b < 0 ? 0 : (b > 255 ? 255 : (unsigned char)b); yy = y[1] << 8; r = (yy + vr) >> 8; g = (yy - ug_plus_vg) >> 8; b = (yy + ub) >> 8; rgb[3] = r < 0 ? 0 : (r > 255 ? 255 : (unsigned char)r); rgb[4] = g < 0 ? 0 : (g > 255 ? 255 : (unsigned char)g); rgb[5] = b < 0 ? 0 : (b > 255 ? 255 : (unsigned char)b); y += 2; rgb += 6; } if ((i & 1) == 0) { uv -= halfwidth * 2; } } } static inline void yuv420p_to_rgb_c(const unsigned char* y, const unsigned char* u, const unsigned char* v, unsigned char* rgb, unsigned int width, unsigned int height) { unsigned int halfwidth = width >> 1; int yy, uu, vv, ug_plus_vg, ub, vr; int r, g, b; unsigned int i, j; for (i = 0; i < height; ++i) { for (j = 0; j < halfwidth; ++j) { yy = y[0] << 8; uu = *(u++) - 128; vv = *(v++) - 128; ug_plus_vg = uu * 88 + vv * 183; ub = uu * 454; vr = vv * 359; r = (yy + vr) >> 8; g = (yy - ug_plus_vg) >> 8; b = (yy + ub) >> 8; rgb[0] = r < 0 ? 0 : (r > 255 ? 255 : (unsigned char)r); rgb[1] = g < 0 ? 0 : (g > 255 ? 255 : (unsigned char)g); rgb[2] = b < 0 ? 0 : (b > 255 ? 255 : (unsigned char)b); yy = y[1] << 8; r = (yy + vr) >> 8; g = (yy - ug_plus_vg) >> 8; b = (yy + ub) >> 8; rgb[3] = r < 0 ? 0 : (r > 255 ? 255 : (unsigned char)r); rgb[4] = g < 0 ? 0 : (g > 255 ? 255 : (unsigned char)g); rgb[5] = b < 0 ? 0 : (b > 255 ? 255 : (unsigned char)b); y += 2; rgb += 6; } if ((i & 1) == 0) { u -= halfwidth; v -= halfwidth; } } } static void vuy422_to_rgb(const unsigned char* yuv, unsigned char* rgb, unsigned int width, unsigned int height) { int yy, uu, vv, ug_plus_vg, ub, vr; int r, g, b; unsigned int total = width * height; total /= 2; while (total--) { yy = yuv[1] << 8; uu = yuv[0] - 128; vv = yuv[2] - 128; ug_plus_vg = uu * 88 + vv * 183; ub = uu * 454; vr = vv * 359; r = (yy + vr) >> 8; g = (yy - ug_plus_vg) >> 8; b = (yy + ub) >> 8; rgb[0] = r < 0 ? 0 : (r > 255 ? 255 : (unsigned char)r); rgb[1] = g < 0 ? 0 : (g > 255 ? 255 : (unsigned char)g); rgb[2] = b < 0 ? 0 : (b > 255 ? 255 : (unsigned char)b); yy = yuv[3] << 8; r = (yy + vr) >> 8; g = (yy - ug_plus_vg) >> 8; b = (yy + ub) >> 8; rgb[3] = r < 0 ? 0 : (r > 255 ? 255 : (unsigned char)r); rgb[4] = g < 0 ? 0 : (g > 255 ? 255 : (unsigned char)g); rgb[5] = b < 0 ? 0 : (b > 255 ? 255 : (unsigned char)b); yuv += 4; rgb += 6; } } // Ecrit un short dans un fichier static void putshort(FILE *file, int i) { int c, c1; c = ((unsigned int ) i) & 0xff; c1 = (((unsigned int) i) >> 8) & 0xff; putc(c, file); putc(c1, file); } // Ecrit un int dans un fichier static void putint(FILE *file, int i) { int c, c1, c2, c3; c = ((unsigned int ) i) & 0xff; c1 = (((unsigned int) i) >> 8) & 0xff; c2 = (((unsigned int) i) >> 16) & 0xff; c3 = (((unsigned int) i) >> 24) & 0xff; putc(c, file); putc(c1, file); putc(c2, file); putc(c3, file); } // write bmp 24 bits in file static void bmp_write24(FILE *file, unsigned char *pic24, int w, int h) { int i, j, pad_bytes; unsigned char *pp; pad_bytes = (4 - ((w * 3) % 4)) & 0x03; // # of pad bytes to write at EOscanline for (i = h - 1; i >= 0; i--) { pp = pic24 + (i * w * 3); fwrite(pp, 3, w, file); if( pad_bytes ) fwrite("\0\0\0", 1, pad_bytes, file); } } // Ecriture d'un buffer image dans un fichier au format BMP static int bmp_write(unsigned char *pic24, // buffer image int w, int h, // resolution de l'image char *filename) { int i, nbits = 24, bperlin, cmaplen = 0; FILE *file; printf("write bmp %s, %dx%d\n", filename, w, h); file = fopen(filename, "wb"); if( file == NULL ) return -1; // nombre d'octets ecrits par ligne bperlin = ((w * nbits + 31) / 32) * 4; // BMP file magic number putc('B', file); putc('M', file); // calcul de la taille du fichier et ecriture i = 14 + // taille du header bitmap 40 + // taille du header d'info bperlin * h; // taille du buffer image putint(file, i); putshort(file, 0); // reserve putshort(file, 0); // reserve putint(file, 14 + 40); putint(file, 40); // taille du header bitmap putint(file, w); // largeur putint(file, h); // hauteur putshort(file, 1); // plans: doit etre 1' putshort(file, nbits); // nombre de bits/pixel = 24 putint(file, 0); // Compression: BI_RGB putint(file, bperlin * h); // taille du buffer image putint(file, 75 * 39); putint(file, 75 * 39); putint(file, 0); // nombre de couleurs used dans la colormap putint(file, 0); // Ecriture du buffer image dans un fichier bmp_write24(file, pic24, w, h); fclose(file); return 0; } #endif
全站熱搜
留言列表