diff options
-rw-r--r-- | converter/ppm/ppmtoyuv.c | 141 |
1 files changed, 82 insertions, 59 deletions
diff --git a/converter/ppm/ppmtoyuv.c b/converter/ppm/ppmtoyuv.c index 8029083a..75f79c1e 100644 --- a/converter/ppm/ppmtoyuv.c +++ b/converter/ppm/ppmtoyuv.c @@ -19,79 +19,102 @@ #include "ppm.h" -int -main(argc, argv) -char **argv; -{ - FILE *ifp; - pixel *pixelrow; - register pixel *pP; - int rows, cols, format, row; - register int col; - pixval maxval; - unsigned long y1, y2=0, u=0, v=0, u0=0, u1, u2, v0=0, v1, v2; - unsigned char *yuvbuf; - - - ppm_init(&argc, argv); - if (argc > 2) pm_usage("[ppmfile]"); - if (argc == 2) ifp = pm_openr(argv[1]); - else ifp = stdin; - - ppm_readppminit(ifp, &cols, &rows, &maxval, &format); +static void +convertRow(const pixel * const pixelrow, + unsigned int const cols, + unsigned char * const yuvBuf, + unsigned long * const uP, + unsigned long * const vP, + unsigned long * const u0P, + unsigned long * const v0P, + unsigned long * const y2CarryP) { + + unsigned int col; + unsigned char * yuvptr; + + for (col = 0, yuvptr = &yuvBuf[0]; col < cols; col += 2) { + unsigned long y1, y2, u1, u2, v1, v2; + + { + /* first pixel gives Y and 0.5 of chroma */ + pixval const r = PPM_GETR(pixelrow[col]); + pixval const g = PPM_GETG(pixelrow[col]); + pixval const b = PPM_GETB(pixelrow[col]); + + y1 = 16829 * r + 33039 * g + 6416 * b + (*y2CarryP & 0xffff); + u1 = -4853 * r - 9530 * g + 14383 * b; + v1 = 14386 * r - 12046 * g - 2340 * b; + } + { + /* second pixel gives Y and 0.25 of chroma */ + pixval const r = PPM_GETR(pixelrow[col + 1]); + pixval const g = PPM_GETG(pixelrow[col + 1]); + pixval const b = PPM_GETB(pixelrow[col + 1]); + + y2 = 16829 * r + 33039 * g + 6416 * b + (y1 & 0xffff); + u2 = -2426 * r - 4765 * g + 7191 * b; + v2 = 7193 * r - 6023 * g - 1170 * b; + } + /* filter the chroma */ + *uP = *u0P + u1 + u2 + (*uP & 0xffff); + *vP = *v0P + v1 + v2 + (*vP & 0xffff); + + *u0P = u2; + *v0P = v2; + + *yuvptr++ = (*uP >> 16) + 128; + *yuvptr++ = (y1 >> 16) + 16; + *yuvptr++ = (*vP >> 16) + 128; + *yuvptr++ = (y2 >> 16) + 16; + + *y2CarryP = y2; + } +} - if (cols % 2 != 0) - pm_error("Image must have even number of columns.\n" - "This image is %u columns wide. Try Pamcut.", cols); - pixelrow = ((pixel*) pm_allocrow( cols, sizeof(pixel) )); - yuvbuf = (unsigned char *) pm_allocrow( cols, 2 ); - for (row = 0; row < rows; ++row) { - unsigned char *yuvptr; +int +main(int argc, const char **argv) { - ppm_readppmrow(ifp, pixelrow, cols, maxval, format); + FILE * ifP; + pixel * pixelrow; + int rows, cols, format; + pixval maxval; + unsigned int row; + unsigned char * yuvBuf; + unsigned long u, v, u0, v0, y2Carry; - for (col = 0, pP = pixelrow, yuvptr=yuvbuf; col < cols; col += 2, ++pP) { - pixval r, g, b; + pm_proginit(&argc, argv); - /* first pixel gives Y and 0.5 of chroma */ - r = PPM_GETR(*pP); - g = PPM_GETG(*pP); - b = PPM_GETB(*pP); + if (argc-1 > 1) + pm_error("Too many arguments: %u. The only possible argument " + "is the name of the input file", argc-1); - y1 = 16829 * r + 33039 * g + 6416 * b + (0xffff & y2); - u1 = -4853 * r - 9530 * g + 14383 * b; - v1 = 14386 * r - 12046 * g - 2340 * b; + if (argc-1 == 1) + ifP = pm_openr(argv[1]); + else + ifP = stdin; - pP++; - /* second pixel just yields a Y and 0.25 U, 0.25 V */ - r = PPM_GETR(*pP); - g = PPM_GETG(*pP); - b = PPM_GETB(*pP); + ppm_readppminit(ifP, &cols, &rows, &maxval, &format); - y2 = 16829 * r + 33039 * g + 6416 * b + (0xffff & y1); - u2 = -2426 * r - 4765 * g + 7191 * b; - v2 = 7193 * r - 6023 * g - 1170 * b; + if (cols % 2 != 0) + pm_error("Image must have even number of columns.\n" + "This image is %u columns wide. Try Pamcut.", cols); - /* filter the chroma */ - u = u0 + u1 + u2 + (0xffff & u); - v = v0 + v1 + v2 + (0xffff & v); + pixelrow = ppm_allocrow(cols); + yuvBuf = (unsigned char *) pm_allocrow(cols, 2); - u0 = u2; - v0 = v2; + for (row = 0, u = v = u0 = v0 = y2Carry = 0; row < rows; ++row) { + ppm_readppmrow(ifP, pixelrow, cols, maxval, format); - *yuvptr++ = (u >> 16) + 128; - *yuvptr++ = (y1 >> 16) + 16; - *yuvptr++ = (v >> 16) + 128; - *yuvptr++ = (y2 >> 16) + 16; - } - fwrite(yuvbuf, cols*2, 1, stdout); - } + convertRow(pixelrow, cols, yuvBuf, &u, &v, &u0, &v0, &y2Carry); + + fwrite(yuvBuf, cols*2, 1, stdout); + } - pm_close(ifp); + pm_close(ifP); - exit(0); + return 0; } |