home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Resource Library: Graphics
/
graphics-16000.iso
/
general
/
convrtrs
/
pbmplus
/
ntpbmsrc.lha
/
netpbm
/
ppm
/
ppmtoyuvsplit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-14
|
6KB
|
197 lines
/* ppmtoyuvsplit.c - convert a portable pixmap into 3 raw files:
** - basename.Y : The Luminance chunk at the size of the Image
** - basename.U : The Chrominance chunk U at 1/4
** - basename.V : The Chrominance chunk V at 1/4
** The subsampled U and V values are made by arithmetic mean.
**
** If CCIR601 is defined, the produced YUV triples are scaled again
** to fit into the smaller range of values for this standard.
**
** by A.Beck
** Internet: Andre_Beck@IRS.Inf.TU-Dresden.de
**
** Based on ppmtoyuv.c
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
/* Wether to create YUV in JFIF(JPEG) or CCIR.601(MPEG) scale */
#define CCIR601
/* Wether to use pm_close() or fake it -- don't ask me why */
/* #define ORIGINAL */
/* ALPHA Kludge by Franky */
#ifdef __alpha
#define myLONG int
#else
#define myLONG long
#endif
#include "ppm.h"
int
main(argc, argv)
char **argv;
{
FILE *ifp,*vf,*uf,*yf;
pixel *pixelrow1,*pixelrow2;
register pixel *pP1,*pP2;
int rows, cols, format, row;
register int col;
pixval maxval;
myLONG y,u,v,y0,y1,y2,y3,u0,u1,u2,u3,v0,v1,v2,v3;
unsigned char *y1buf,*y2buf,*ubuf,*vbuf;
char ufname[256],vfname[256],yfname[256];
ppm_init(&argc, argv);
if ((argc>3)||(argc<2)) pm_usage("basename [ppmfile]");
if (argc == 3) ifp = pm_openr(argv[2]);
else ifp = stdin;
strcpy(ufname,argv[1]);
strcpy(vfname,argv[1]);
strcpy(yfname,argv[1]);
strcat(ufname,".U");
strcat(vfname,".V");
strcat(yfname,".Y");
uf = fopen(ufname,"wb");
vf = fopen(vfname,"wb");
yf = fopen(yfname,"wb");
if(!(uf && vf && yf)) {
perror("error opening output files");
exit(0);
}
ppm_readppminit(ifp, &cols, &rows, &maxval, &format);
if(cols & 1) fprintf(stderr,
"%s: Warning: odd columns count, exceed ignored\n",
argv[0]);
if(rows & 1) fprintf(stderr,
"%s: Warning: odd rows count, exceed ignored\n",
argv[0]);
pixelrow1 = ((pixel*) pm_allocrow( cols, sizeof(pixel) ));
pixelrow2 = ((pixel*) pm_allocrow( cols, sizeof(pixel) ));
y1buf = (unsigned char *) pm_allocrow( cols, 1 );
y2buf = (unsigned char *) pm_allocrow( cols, 1 );
ubuf = (unsigned char *) pm_allocrow( cols, 1 );
vbuf = (unsigned char *) pm_allocrow( cols, 1 );
for (row = 0; row < (rows & ~1); row += 2) {
unsigned char *y1ptr,*y2ptr,*uptr,*vptr;
ppm_readppmrow(ifp, pixelrow1, cols, maxval, format);
ppm_readppmrow(ifp, pixelrow2, cols, maxval, format);
pP1 = pixelrow1; pP2 = pixelrow2;
y1ptr = y1buf; y2ptr = y2buf; vptr = vbuf; uptr = ubuf;
for (col = 0 ; col < (cols & ~1); col += 2) {
pixval r0,g0,b0,r1,g1,b1,r2,g2,b2,r3,g3,b3;
/* first pixel */
r0 = PPM_GETR(*pP1);
g0 = PPM_GETG(*pP1);
b0 = PPM_GETB(*pP1);
pP1++;
/* 2nd pixel */
r1 = PPM_GETR(*pP1);
g1 = PPM_GETG(*pP1);
b1 = PPM_GETB(*pP1);
pP1++;
/* 3rd pixel */
r2 = PPM_GETR(*pP2);
g2 = PPM_GETG(*pP2);
b2 = PPM_GETB(*pP2);
pP2++;
/* 4th pixel */
r3 = PPM_GETR(*pP2);
g3 = PPM_GETG(*pP2);
b3 = PPM_GETB(*pP2);
pP2++;
/* The JFIF RGB to YUV Matrix for $00010000 = 1.0
[Y] [19595 38469 7471][R]
[U] = [-11056 -21712 32768][G]
[V] [32768 -27440 -5328][B]
*/
y0 = 19595 * r0 + 38469 * g0 + 7471 * b0;
u0 = -11056 * r0 - 21712 * g0 + 32768 * b0;
v0 = 32768 * r0 - 27440 * g0 - 5328 * b0;
y1 = 19595 * r1 + 38469 * g1 + 7471 * b1;
u1 = -11056 * r1 - 21712 * g1 + 32768 * b1;
v1 = 32768 * r1 - 27440 * g1 - 5328 * b1;
y2 = 19595 * r2 + 38469 * g2 + 7471 * b2;
u2 = -11056 * r2 - 21712 * g2 + 32768 * b2;
v2 = 32768 * r2 - 27440 * g2 - 5328 * b2;
y3 = 19595 * r3 + 38469 * g3 + 7471 * b3;
u3 = -11056 * r3 - 21712 * g3 + 32768 * b3;
v3 = 32768 * r3 - 27440 * g3 - 5328 * b3;
/* mean the chroma for subsampling */
u = (u0+u1+u2+u3)>>2;
v = (v0+v1+v2+v3)>>2;
#ifdef CCIR601
y0 = (y0 * 219)/255 + 1048576;
y1 = (y1 * 219)/255 + 1048576;
y2 = (y2 * 219)/255 + 1048576;
y3 = (y3 * 219)/255 + 1048576;
u = (u * 224)/255 ;
v = (v * 224)/255 ;
#endif
*y1ptr++ = (y0 >> 16) ;
*y1ptr++ = (y1 >> 16) ;
*y2ptr++ = (y2 >> 16) ;
*y2ptr++ = (y3 >> 16) ;
*uptr++ = (u >> 16)+128 ;
*vptr++ = (v >> 16)+128 ;
}
fwrite(y1buf, (cols & ~1), 1, yf);
fwrite(y2buf, (cols & ~1), 1, yf);
fwrite(ubuf, cols/2, 1, uf);
fwrite(vbuf, cols/2, 1, vf);
}
/* I dunno why pm_close sees an error... get rid of it */
#ifdef ORIGINAL
pm_close(ifp);
#else
if(ifp != stdin) fclose(ifp);
#endif
fclose(yf);
fclose(uf);
fclose(vf);
exit(0);
}