home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2008 January / Mac_easy_01_08.iso / Software / Online / Chat / macam.0.9.1.dmg / macam source / utilities / yuv2rgbCPIA420.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-03-03  |  11.2 KB  |  287 lines

  1. /*
  2.  macam - webcam app and QuickTime driver component
  3.  Copyright (C) 2002 Matthias Krauss (macam@matthias-krauss.de)
  4.  
  5.  This program is free software; you can redistribute it and/or modify
  6.  it under the terms of the GNU General Public License as published by
  7.  the Free Software Foundation; either version 2 of the License, or
  8.  (at your option) any later version.
  9.  
  10.  This program is distributed in the hope that it will be useful,
  11.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  GNU General Public License for more details.
  14.  
  15.  You should have received a copy of the GNU General Public License
  16.  along with this program; if not, write to the Free Software
  17.  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  $Id: yuv2rgbCPIA420.c,v 1.2 2006/03/03 18:32:36 hxr Exp $
  19. */
  20.  
  21. /*
  22.  
  23. This file contains just a raw function body and is intended to be #included from other files, such as yuv2rgb.c
  24.  
  25. The function prototype has to be:
  26.  
  27. void <whatever>(int width, int height, unsigned char *src, unsigned char *dst, long srcRowExtra, long dstRowExtra);
  28.  
  29. */
  30.     unsigned char* s1;                //Source buffer run: first line
  31.     unsigned char* s2;                //Source buffer run: second line
  32.     unsigned char* d1;                //Destination buffer run: first line
  33.     unsigned char* d2;                //Destination buffer run: first line
  34.     long x,y;                    //loop counters
  35.     long y11,y12,y13,y14,y21,y22,y23,y24;    //The y components in yuv
  36.     long u1,u1g,u1b,u2,u2g,u2b;            //The raw u components and the u differences
  37.     long v1,v1r,v1g,v2,v2r,v2g;            //The raw v components and the v differences
  38.     long r11,g11,b11,r12,g12,b12,r13,g13,b13,r14,g14,b14;    //Destination rgb: first line
  39.     long r21,g21,b21,r22,g22,b22,r23,g23,b23,r24,g24,b24;    //Destination rgb: second line
  40.     long dstRowBytes;                //EXCLUDING the extra part, just the raw data length per row
  41.     long srcRow1Extra,srcRow2Extra;        //Bytes to skip after each row
  42.     unsigned long ul1,ul2,ul3,ul4,ul5,ul6,ul7,ul8;     //Temp vars to access memory
  43. #ifdef YUV2RGB_ALPHA
  44.     short bpp=4;
  45. #else
  46.     short bpp=3;
  47. #pragma unused(ul4)
  48. #pragma unused(ul8)
  49. #endif
  50.     width/=4;                    //We work in 4 x 2 blocks
  51.     height/=2;
  52.     dstRowBytes=4*bpp*width;
  53.     s1=src;
  54.     s2=src+width*8+srcRowExtra;
  55.     srcRow1Extra=2*srcRowExtra+4*width;        //skip line 2 since we're working two lines at once
  56.     srcRow2Extra=2*srcRowExtra+8*width;        //skip line 1 since we're working two lines at once
  57.     d1=dst;
  58.     d2=dst+width*4*bpp+dstRowExtra;
  59. #ifndef YUV2RGB_FLIP
  60.     dstRowExtra=2*dstRowExtra+dstRowBytes;    //Extend to skip one line since we're working two lines at once
  61. #else
  62.     dstRowExtra=2*dstRowExtra+3*dstRowBytes;    //From the start of a line to the end of the second next
  63.     d1+=dstRowBytes;
  64.     d2+=dstRowBytes;
  65. #endif
  66.     for (y=height;y;y--) {
  67.         for (x=width;x;x--) {
  68. //Read from source buffer
  69. //            *** Byte-swapping issues here!!! ***
  70.             ul1=CFSwapInt32HostToBig(*((unsigned  long*)(s1))); s1+=4;    //Read yuyv in line 1
  71.             ul2=CFSwapInt32HostToBig(*((unsigned  long*)(s1))); s1+=4;    //Read yuyv in line 1
  72.             ul3=CFSwapInt32HostToBig(*((unsigned  long*)(s2))); s2+=4;    //Read y in line 2
  73. //Extract yuv pixel data
  74.             y11=(ul1&0xff000000)>>16;
  75.             u1 =((ul1&0x00ff0000)>>16)-128;
  76.             y12=(ul1&0x0000ff00);
  77.             v1 =(ul1&0x000000ff)-128;
  78.             y13=(ul2&0xff000000)>>16;
  79.             u2 =((ul2&0x00ff0000)>>16)-128;
  80.             y14=(ul2&0x0000ff00);
  81.             v2 =(ul2&0x000000ff)-128;
  82.             y21=(ul3&0xff000000)>>16;
  83.             y22=(ul3&0x00ff0000)>>8;
  84.             y23=(ul3&0x0000ff00);
  85.             y24=(ul3&0x000000ff)<<8;
  86. //convert yuv to rgb: calculate difference coefficients
  87.             u1g=u1*88;
  88.             u1b=u1*454;
  89.             v1r=v1*359;
  90.             v1g=v1*183;
  91.             u2g=u2*88;
  92.             u2b=u2*454;
  93.             v2r=v2*359;
  94.             v2g=v2*183;
  95. //convert yuv to rgb: assemble rgb
  96.             r11=(y11+v1r)/256;
  97.             g11=(y11-u1g-v1g)/256;
  98.             b11=(y11+u1b)/256;
  99.             r12=(y12+v1r)/256;
  100.             g12=(y12-u1g-v1g)/256;
  101.             b12=(y12+u1b)/256;
  102.             r13=(y13+v2r)/256;
  103.             g13=(y13-u2g-v2g)/256;
  104.             b13=(y13+u2b)/256;
  105.             r14=(y14+v2r)/256;
  106.             g14=(y14-u2g-v2g)/256;
  107.             b14=(y14+u2b)/256;
  108.             r21=(y21+v1r)/256;
  109.             g21=(y21-u1g-v1g)/256;
  110.             b21=(y21+u1b)/256;
  111.             r22=(y22+v1r)/256;
  112.             g22=(y22-u1g-v1g)/256;
  113.             b22=(y22+u1b)/256;
  114.             r23=(y23+v2r)/256;
  115.             g23=(y23-u2g-v2g)/256;
  116.             b23=(y23+u2b)/256;
  117.             r24=(y24+v2r)/256;
  118.             g24=(y24-u2g-v2g)/256;
  119.             b24=(y24+u2b)/256;
  120. //convert yuv to rgb: check value bounds
  121.             r11=CLAMP(r11,0,255);
  122.             g11=CLAMP(g11,0,255);
  123.             b11=CLAMP(b11,0,255);
  124.             r12=CLAMP(r12,0,255);
  125.             g12=CLAMP(g12,0,255);
  126.             b12=CLAMP(b12,0,255);
  127.             r13=CLAMP(r13,0,255);
  128.             g13=CLAMP(g13,0,255);
  129.             b13=CLAMP(b13,0,255);
  130.             r14=CLAMP(r14,0,255);
  131.             g14=CLAMP(g14,0,255);
  132.             b14=CLAMP(b14,0,255);
  133.             r21=CLAMP(r21,0,255);
  134.             g21=CLAMP(g21,0,255);
  135.             b21=CLAMP(b21,0,255);
  136.             r22=CLAMP(r22,0,255);
  137.             g22=CLAMP(g22,0,255);
  138.             b22=CLAMP(b22,0,255);
  139.             r23=CLAMP(r23,0,255);
  140.             g23=CLAMP(g23,0,255);
  141.             b23=CLAMP(b23,0,255);
  142.             r24=CLAMP(r24,0,255);
  143.             g24=CLAMP(g24,0,255);
  144.             b24=CLAMP(b24,0,255);
  145. //Assemble longs from rgb data
  146. #ifndef YUV2RGB_ALPHA
  147. #ifdef YUV2RGB_FLIP
  148. //3bpp, flipped assembly
  149.             ul3=(((unsigned long)r14)<<24)
  150.                 |(((unsigned long)g14)<<16)
  151.                 |(((unsigned long)b14)<<8)
  152.                 |(((unsigned long)r13));
  153.             ul2=(((unsigned long)g13)<<24)
  154.                 |(((unsigned long)b13)<<16)
  155.                 |(((unsigned long)r12)<<8)
  156.                 |(((unsigned long)g12));
  157.             ul1=(((unsigned long)b12)<<24)
  158.                 |(((unsigned long)r11)<<16)
  159.                 |(((unsigned long)g11)<<8)
  160.                 |(((unsigned long)b11));
  161.             ul7=(((unsigned long)r24)<<24)
  162.                 |(((unsigned long)g24)<<16)
  163.                 |(((unsigned long)b24)<<8)
  164.                 |(((unsigned long)r23));
  165.             ul6=(((unsigned long)g23)<<24)
  166.                 |(((unsigned long)b23)<<16)
  167.                 |(((unsigned long)r22)<<8)
  168.                 |(((unsigned long)g22));
  169.             ul5=(((unsigned long)b22)<<24)
  170.                 |(((unsigned long)r21)<<16)
  171.                 |(((unsigned long)g21)<<8)
  172.                 |(((unsigned long)b21));
  173. #else
  174. //3bpp, unflipped assembly
  175.             ul1=(((unsigned long)r11)<<24)
  176.                 |(((unsigned long)g11)<<16)
  177.                 |(((unsigned long)b11)<<8)
  178.                 |(((unsigned long)r12));
  179.             ul2=(((unsigned long)g12)<<24)
  180.                 |(((unsigned long)b12)<<16)
  181.                 |(((unsigned long)r13)<<8)
  182.                 |(((unsigned long)g13));
  183.             ul3=(((unsigned long)b13)<<24)
  184.                 |(((unsigned long)r14)<<16)
  185.                 |(((unsigned long)g14)<<8)
  186.                 |(((unsigned long)b14));
  187.             ul5=(((unsigned long)r21)<<24)
  188.                 |(((unsigned long)g21)<<16)
  189.                 |(((unsigned long)b21)<<8)
  190.                 |(((unsigned long)r22));
  191.             ul6=(((unsigned long)g22)<<24)
  192.                 |(((unsigned long)b22)<<16)
  193.                 |(((unsigned long)r23)<<8)
  194.                 |(((unsigned long)g23));
  195.             ul7=(((unsigned long)b23)<<24)
  196.                 |(((unsigned long)r24)<<16)
  197.                 |(((unsigned long)g24)<<8)
  198.                 |(((unsigned long)b24));
  199. #endif
  200. #else
  201. //4bpp assembly - no matter if flipped or unflipped
  202.             ul1=0xff000000
  203.                 |(((unsigned long)r11)<<16)
  204.                 |(((unsigned long)g11)<<8)
  205.                 |(((unsigned long)b11));
  206.             ul2=0xff000000
  207.                 |(((unsigned long)r12)<<16)
  208.                 |(((unsigned long)g12)<<8)
  209.                 |(((unsigned long)b12));
  210.             ul3=0xff000000
  211.                 |(((unsigned long)r13)<<16)
  212.                 |(((unsigned long)g13)<<8)
  213.                 |(((unsigned long)b13));
  214.             ul4=0xff000000
  215.                 |(((unsigned long)r14)<<16)
  216.                 |(((unsigned long)g14)<<8)
  217.                 |(((unsigned long)b14));
  218.             ul5=0xff000000
  219.                 |(((unsigned long)r21)<<16)
  220.                 |(((unsigned long)g21)<<8)
  221.                 |(((unsigned long)b21));
  222.             ul6=0xff000000
  223.                 |(((unsigned long)r22)<<16)
  224.                 |(((unsigned long)g22)<<8)
  225.                 |(((unsigned long)b22));
  226.             ul7=0xff000000
  227.                 |(((unsigned long)r23)<<16)
  228.                 |(((unsigned long)g23)<<8)
  229.                 |(((unsigned long)b23));
  230.             ul8=0xff000000
  231.                 |(((unsigned long)r24)<<16)
  232.                 |(((unsigned long)g24)<<8)
  233.                 |(((unsigned long)b24));
  234. #endif
  235. //Output to destination buffer
  236. #ifdef YUV2RGB_FLIP
  237. #ifdef YUV2RGB_ALPHA
  238.             d1-=16;
  239.             *((unsigned long*)(d1+12))=CFSwapInt32BigToHost(ul1);
  240.             *((unsigned long*)(d1+ 8))=CFSwapInt32BigToHost(ul2);
  241.             *((unsigned long*)(d1+ 4))=CFSwapInt32BigToHost(ul3);
  242.             *((unsigned long*)(d1   ))=CFSwapInt32BigToHost(ul4);
  243.             d2-=16;
  244.             *((unsigned long*)(d2+12))=CFSwapInt32BigToHost(ul5);
  245.             *((unsigned long*)(d2+ 8))=CFSwapInt32BigToHost(ul6);
  246.             *((unsigned long*)(d2+ 4))=CFSwapInt32BigToHost(ul7);
  247.             *((unsigned long*)(d2   ))=CFSwapInt32BigToHost(ul8);
  248. #else    //YUV2RGB_ALPHA
  249.             d1-=12;
  250.             *((unsigned long*)(d1+ 8))=CFSwapInt32BigToHost(ul1);
  251.             *((unsigned long*)(d1+ 4))=CFSwapInt32BigToHost(ul2);
  252.             *((unsigned long*)(d1   ))=CFSwapInt32BigToHost(ul3);
  253.             d2-=12;
  254.             *((unsigned long*)(d2+ 8))=CFSwapInt32BigToHost(ul5);
  255.             *((unsigned long*)(d2+ 4))=CFSwapInt32BigToHost(ul6);
  256.             *((unsigned long*)(d2   ))=CFSwapInt32BigToHost(ul7);
  257. #endif    //YUV2RGB_ALPHA
  258. #else    //YUV2RGB_FLIP
  259. #ifdef YUV2RGB_ALPHA
  260.             *((unsigned long*)(d1))=CFSwapInt32BigToHost(ul1);
  261.             *((unsigned long*)(d1+4))=CFSwapInt32BigToHost(ul2);
  262.             *((unsigned long*)(d1+8))=CFSwapInt32BigToHost(ul3);
  263.             *((unsigned long*)(d1+12))=CFSwapInt32BigToHost(ul4);
  264.             d1+=16;
  265.             *((unsigned long*)(d2))=CFSwapInt32BigToHost(ul5);
  266.             *((unsigned long*)(d2+4))=CFSwapInt32BigToHost(ul6);
  267.             *((unsigned long*)(d2+8))=CFSwapInt32BigToHost(ul7);
  268.             *((unsigned long*)(d2+12))=CFSwapInt32BigToHost(ul8);
  269.             d2+=16;
  270. #else    //YUV2RGB_ALPHA
  271.             *((unsigned long*)(d1))=CFSwapInt32BigToHost(ul1);
  272.             *((unsigned long*)(d1+4))=CFSwapInt32BigToHost(ul2);
  273.             *((unsigned long*)(d1+8))=CFSwapInt32BigToHost(ul3);
  274.             d1+=12;
  275.             *((unsigned long*)(d2))=CFSwapInt32BigToHost(ul5);
  276.             *((unsigned long*)(d2+4))=CFSwapInt32BigToHost(ul6);
  277.             *((unsigned long*)(d2+8))=CFSwapInt32BigToHost(ul7);
  278.             d2+=12;
  279. #endif    //YUV2RGB_ALPHA
  280. #endif    //YUV2RGB_FLIP
  281.         }
  282.         s1+=srcRow1Extra;
  283.         s2+=srcRow2Extra;
  284.         d1+=dstRowExtra;
  285.         d2+=dstRowExtra;
  286.     }
  287. //End of included, preprocessor-customized code