Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

rgbtoycc.c

Go to the documentation of this file.
00001 /*===========================================================================*
00002  * rgbtoycc.c                                                                *
00003  *                                                                           *
00004  *      Procedures to convert from RGB space to YUV space                    *
00005  *                                                                           *
00006  * EXPORTED PROCEDURES:                                                      *
00007  *      PNMtoYUV                                                             *
00008  *      PPMtoYUV                                                             *
00009  *                                                                           *
00010  *===========================================================================*/
00011 
00012 /*
00013  * Copyright (c) 1995 The Regents of the University of California.
00014  * All rights reserved.
00015  *
00016  * Permission to use, copy, modify, and distribute this software and its
00017  * documentation for any purpose, without fee, and without written agreement is
00018  * hereby granted, provided that the above copyright notice and the following
00019  * two paragraphs appear in all copies of this software.
00020  *
00021  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
00022  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00023  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
00024  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025  *
00026  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00027  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00028  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00029  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
00030  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00031  */
00032 
00033 /*  
00034  *  $Header: /misc/elrond0/share/cvs/AFNI/src/mpeg_encodedir/rgbtoycc.c,v 1.5 2004/04/02 15:12:41 rwcox Exp $
00035  *  $Log: rgbtoycc.c,v $
00036  *  Revision 1.5  2004/04/02 15:12:41  rwcox
00037  *  Cput
00038  *
00039  *  Revision 1.4  2004/02/05 21:32:23  rwcox
00040  *  Cput
00041  *
00042  *  Revision 1.3  2003/12/23 13:50:08  rwcox
00043  *  Cput
00044  *
00045  *  Revision 1.2  2003/12/03 14:46:14  rwcox
00046  *  Cput
00047  *
00048  *  Revision 1.1  2001/12/17 16:11:55  rwcox
00049  *  Cadd
00050  *
00051  *  Revision 1.5  1995/08/14 22:32:16  smoot
00052  *  added better error message
00053  *
00054  *  Revision 1.4  1995/01/19 23:09:23  eyhung
00055  *  Changed copyrights
00056  *
00057  * Revision 1.3  1994/11/12  02:12:00  keving
00058  * nothing
00059  *
00060  * Revision 1.2  1993/12/22  19:19:01  keving
00061  * nothing
00062  *
00063  * Revision 1.2  1993/12/22  19:19:01  keving
00064  * nothing
00065  *
00066  * Revision 1.1  1993/07/22  22:23:43  keving
00067  * nothing
00068  *
00069  */
00070 
00071 
00072 /*==============*
00073  * HEADER FILES *
00074  *==============*/
00075 
00076 #include "all.h"
00077 #include "frame.h"
00078 #include "fsize.h"
00079 #include "rgbtoycc.h"
00080 
00081 
00082 /*=====================*
00083  * EXPORTED PROCEDURES *
00084  *=====================*/
00085 
00086 
00087 /*===========================================================================*
00088  *
00089  * PNMtoYUV
00090  *
00091  *      convert PNM data into YUV data
00092  *
00093  * RETURNS:     nothing
00094  *
00095  * SIDE EFFECTS:    none
00096  *
00097  *===========================================================================*/
00098 void
00099 PNMtoYUV(frame)
00100     MpegFrame *frame;
00101 {
00102     register int x, y;
00103     register uint8 *dy0, *dy1;
00104     register uint8 *dcr, *dcb;
00105     register xel *src0, *src1;
00106     register int ydivisor, cdivisor;
00107     static boolean  first = TRUE;
00108     static float  mult299[1024], mult587[1024], mult114[1024];
00109     static float  mult16874[1024], mult33126[1024], mult5[1024];
00110     static float mult41869[1024], mult08131[1024];
00111 
00112     if ( first ) {
00113         register int index;
00114         register int maxValue;
00115 
00116         maxValue = frame->rgb_maxval;
00117 
00118         for ( index = 0; index <= maxValue; index++ ) {
00119             mult299[index] = index*0.29900;
00120             mult587[index] = index*0.58700;
00121             mult114[index] = index*0.11400;
00122             mult16874[index] = -0.16874*index;
00123             mult33126[index] = -0.33126*index;
00124             mult5[index] = index*0.50000;
00125             mult41869[index] = -0.41869*index;
00126             mult08131[index] = -0.08131*index;
00127         }
00128         
00129         first = FALSE;
00130     }
00131 
00132     Frame_AllocYCC(frame);
00133 
00134     /*
00135      * okay.  Now, convert everything into YCrCb space. (the specific
00136      * numbers come from the JPEG source, jccolor.c) The conversion
00137      * equations to be implemented are therefore
00138      *
00139      * Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
00140      * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B
00141      * Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B
00142      */
00143 
00144 /* ydivisor should be a FLOAT, shouldn't it?!?! */
00145 
00146     ydivisor = (frame->rgb_maxval + 1) >> 8;    /* for normalizing values
00147                                                  * 0-255, divide by 256 */
00148     cdivisor = (ydivisor << 2);     /* because we're averaging 4 pixels */
00149 
00150     for (y = 0; y < Fsize_y; y += 2) {
00151         for (x = 0, src0 = frame->rgb_data[y], src1 = frame->rgb_data[y + 1],
00152              dy0 = frame->orig_y[y], dy1 = frame->orig_y[y + 1],
00153              dcr = frame->orig_cr[y >> 1], dcb = frame->orig_cb[y >> 1];
00154              x < Fsize_x;
00155              x += 2, dy0 += 2, dy1 += 2, dcr++,
00156              dcb++, src0 += 2, src1 += 2) {
00157 
00158             *dy0 = (mult299[PPM_GETR(*src0)] +
00159                     mult587[PPM_GETG(*src0)] +
00160                     mult114[PPM_GETB(*src0)]) / ydivisor;
00161 
00162             *dy1 = (mult299[PPM_GETR(*src1)] +
00163                     mult587[PPM_GETG(*src1)] +
00164                     mult114[PPM_GETB(*src1)]) / ydivisor;
00165 
00166             dy0[1] = (mult299[PPM_GETR(src0[1])] +
00167                       mult587[PPM_GETG(src0[1])] +
00168                       mult114[PPM_GETB(src0[1])]) / ydivisor;
00169 
00170             dy1[1] = (mult299[PPM_GETR(src1[1])] +
00171                       mult587[PPM_GETG(src1[1])] +
00172                       mult114[PPM_GETB(src1[1])]) / ydivisor;
00173 
00174             *dcb = ((mult16874[PPM_GETR(*src0)] +
00175                      mult33126[PPM_GETG(*src0)] +
00176                      mult5[PPM_GETB(*src0)] +
00177                      mult16874[PPM_GETR(*src1)] +
00178                      mult33126[PPM_GETG(*src1)] +
00179                      mult5[PPM_GETB(*src1)] +
00180                      mult16874[PPM_GETR(src0[1])] +
00181                      mult33126[PPM_GETG(src0[1])] +
00182                      mult5[PPM_GETB(src0[1])] +
00183                      mult16874[PPM_GETR(src1[1])] +
00184                      mult33126[PPM_GETG(src1[1])] +
00185                      mult5[PPM_GETB(src1[1])]) / cdivisor) + 128;
00186 
00187             *dcr = ((mult5[PPM_GETR(*src0)] +
00188                      mult41869[PPM_GETG(*src0)] +
00189                      mult08131[PPM_GETB(*src0)] +
00190                      mult5[PPM_GETR(*src1)] +
00191                      mult41869[PPM_GETG(*src1)] +
00192                      mult08131[PPM_GETB(*src1)] +
00193                      mult5[PPM_GETR(src0[1])] +
00194                      mult41869[PPM_GETG(src0[1])] +
00195                      mult08131[PPM_GETB(src0[1])] +
00196                      mult5[PPM_GETR(src1[1])] +
00197                      mult41869[PPM_GETG(src1[1])] +
00198                      mult08131[PPM_GETB(src1[1])]) / cdivisor) + 128;
00199 
00200             /* if your floating point is faster than your loads, you
00201              * might consider this:
00202              */
00203 #ifdef BLEAH
00204             *dy0 = (PPM_GETR(*src0) * 0.29900 +
00205                     PPM_GETG(*src0) * 0.58700 +
00206                     PPM_GETB(*src0) * 0.11400) / ydivisor;
00207             *dy1 = (PPM_GETR(*src1) * 0.29900 +
00208                     PPM_GETG(*src1) * 0.58700 +
00209                     PPM_GETB(*src1) * 0.11400) / ydivisor;
00210 
00211             dy0[1] = (PPM_GETR(src0[1]) * 0.29900 +
00212                       PPM_GETG(src0[1]) * 0.58700 +
00213                       PPM_GETB(src0[1]) * 0.11400) / ydivisor;
00214 
00215             dy1[1] = (PPM_GETR(src1[1]) * 0.29900 +
00216                       PPM_GETG(src1[1]) * 0.58700 +
00217                       PPM_GETB(src1[1]) * 0.11400) / ydivisor;
00218 
00219             *dcb = ((PPM_GETR(*src0) * -0.16874 +
00220                      PPM_GETG(*src0) * -0.33126 +
00221                      PPM_GETB(*src0) * 0.50000 +
00222                      PPM_GETR(*src1) * -0.16874 +
00223                      PPM_GETG(*src1) * -0. +
00224                      PPM_GETB(*src1) * 0.50000 +
00225                      PPM_GETR(src0[1]) * -0.16874 +
00226                      PPM_GETG(src0[1]) * -0.33126 +
00227                      PPM_GETB(src0[1]) * 0.50000 +
00228                      PPM_GETR(src1[1]) * -0.16874 +
00229                      PPM_GETG(src1[1]) * -0.33126 +
00230                      PPM_GETB(src1[1]) * 0.50000) / cdivisor) + 128;
00231 
00232             *dcr = ((PPM_GETR(*src0) * 0.50000 +
00233                      PPM_GETG(*src0) * -0.41869 +
00234                      PPM_GETB(*src0) * -0.08131 +
00235                      PPM_GETR(*src1) * 0.50000 +
00236                      PPM_GETG(*src1) * -0.41869 +
00237                      PPM_GETB(*src1) * -0.08131 +
00238                      PPM_GETR(src0[1]) * 0.50000 +
00239                      PPM_GETG(src0[1]) * -0.41869 +
00240                      PPM_GETB(src0[1]) * -0.08131 +
00241                      PPM_GETR(src1[1]) * 0.50000 +
00242                      PPM_GETG(src1[1]) * -0.41869 +
00243                      PPM_GETB(src1[1]) * -0.08131) / cdivisor) + 128;
00244 #endif
00245 
00246             DBG_PRINT(("%3d,%3d: (%3d,%3d,%3d) --> (%3d,%3d,%3d)\n", x, y, PPM_GETR(*src0), PPM_GETG(*src0), PPM_GETB(*src0), *dy0, *dcb, *dcr));
00247         }
00248     }
00249 }
00250 
00251 
00252 
00253 /*===========================================================================*
00254  *
00255  * PPMtoYUV
00256  *
00257  *      convert PPM data into YUV data
00258  *      same as PNMtoYUV, except extracts data from ppm_data, and
00259  *      assumes that ydivisor = 1
00260  *
00261  * RETURNS:     nothing
00262  *
00263  * SIDE EFFECTS:    none
00264  *
00265  *===========================================================================*/
00266 void
00267 PPMtoYUV(frame)
00268     MpegFrame *frame;
00269 {
00270     register int x, y;
00271     register uint8 *dy0, *dy1;
00272     register uint8 *dcr, *dcb;
00273     register uint8 *src0, *src1;
00274     register int cdivisor;
00275     static boolean  first = TRUE;
00276     static float  mult299[1024], mult587[1024], mult114[1024];
00277     static float  mult16874[1024], mult33126[1024], mult5[1024];
00278     static float mult41869[1024], mult08131[1024];
00279 
00280     if ( first ) {
00281         register int index;
00282         register int maxValue;
00283 
00284         maxValue = frame->rgb_maxval;
00285 
00286         for ( index = 0; index <= maxValue; index++ ) {
00287             mult299[index] = index*0.29900;
00288             mult587[index] = index*0.58700;
00289             mult114[index] = index*0.11400;
00290             mult16874[index] = -0.16874*index;
00291             mult33126[index] = -0.33126*index;
00292             mult5[index] = index*0.50000;
00293             mult41869[index] = -0.41869*index;
00294             mult08131[index] = -0.08131*index;
00295         }
00296         
00297         first = FALSE;
00298     }
00299 
00300     Frame_AllocYCC(frame);
00301 
00302     /* assume ydivisor = 1, so cdivisor = 4 */
00303     if ( frame->rgb_maxval != 255 ) {
00304         fprintf(stderr, "PPM max gray value != 255.  Exiting.\n\tTry PNM type, not PPM\n");
00305         exit(1);
00306     }
00307 
00308     cdivisor = 4;
00309 
00310     for (y = 0; y < Fsize_y; y += 2) {
00311         src0 = frame->ppm_data[y];
00312         src1 = frame->ppm_data[y + 1];
00313         dy0 = frame->orig_y[y];
00314         dy1 = frame->orig_y[y + 1];
00315         dcr = frame->orig_cr[y >> 1];
00316         dcb = frame->orig_cb[y >> 1];
00317 
00318         for ( x = 0; x < Fsize_x; x += 2, dy0 += 2, dy1 += 2, dcr++,
00319                                    dcb++, src0 += 6, src1 += 6) {
00320             *dy0 = (mult299[*src0] +
00321                     mult587[src0[1]] +
00322                     mult114[src0[2]]);
00323 
00324             *dy1 = (mult299[*src1] +
00325                     mult587[src1[1]] +
00326                     mult114[src1[2]]);
00327 
00328             dy0[1] = (mult299[src0[3]] +
00329                       mult587[src0[4]] +
00330                       mult114[src0[5]]);
00331 
00332             dy1[1] = (mult299[src1[3]] +
00333                       mult587[src1[4]] +
00334                       mult114[src1[5]]);
00335 
00336             *dcb = ((mult16874[*src0] +
00337                      mult33126[src0[1]] +
00338                      mult5[src0[2]] +
00339                      mult16874[*src1] +
00340                      mult33126[src1[1]] +
00341                      mult5[src1[2]] +
00342                      mult16874[src0[3]] +
00343                      mult33126[src0[4]] +
00344                      mult5[src0[5]] +
00345                      mult16874[src1[3]] +
00346                      mult33126[src1[4]] +
00347                      mult5[src1[5]]) / cdivisor) + 128;
00348 
00349             *dcr = ((mult5[*src0] +
00350                      mult41869[src0[1]] +
00351                      mult08131[src0[2]] +
00352                      mult5[*src1] +
00353                      mult41869[src1[1]] +
00354                      mult08131[src1[2]] +
00355                      mult5[src0[3]] +
00356                      mult41869[src0[4]] +
00357                      mult08131[src0[5]] +
00358                      mult5[src1[3]] +
00359                      mult41869[src1[4]] +
00360                      mult08131[src1[5]]) / cdivisor) + 128;
00361 
00362             DBG_PRINT(("%3d,%3d: (%3d,%3d,%3d) --> (%3d,%3d,%3d)\n", x, y, PPM_GETR(*src0), PPM_GETG(*src0), PPM_GETB(*src0), *dy0, *dcb, *dcr));
00363         }
00364     }
00365 }
00366 
 

Powered by Plone

This site conforms to the following standards: