1e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/* 2e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Copyright (C) 2011 The Android Open Source Project 3e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * 4e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * you may not use this file except in compliance with the License. 6e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * You may obtain a copy of the License at 7e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * 8e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * http://www.apache.org/licenses/LICENSE-2.0 9e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * 10e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Unless required by applicable law or agreed to in writing, software 11e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS, 12e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * See the License for the specific language governing permissions and 14e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * limitations under the License. 15e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen */ 16e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 17e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/////////////////////////////////////////////////// 18e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// ImageUtils.cpp 19e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// $Id: ImageUtils.cpp,v 1.12 2011/06/17 13:35:48 mbansal Exp $ 20e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 21e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 22e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <stdio.h> 23e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <stdlib.h> 24e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <sys/time.h> 25e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 26e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include "ImageUtils.h" 27e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 2841a2e9735136f372de95652d0828600282c8e967mbansalvoid ImageUtils::rgba2yvu(ImageType out, ImageType in, int width, int height) 2941a2e9735136f372de95652d0828600282c8e967mbansal{ 3041a2e9735136f372de95652d0828600282c8e967mbansal int r,g,b, a; 3141a2e9735136f372de95652d0828600282c8e967mbansal ImageType yimg = out; 3241a2e9735136f372de95652d0828600282c8e967mbansal ImageType vimg = yimg + width*height; 3341a2e9735136f372de95652d0828600282c8e967mbansal ImageType uimg = vimg + width*height; 3441a2e9735136f372de95652d0828600282c8e967mbansal ImageType image = in; 3541a2e9735136f372de95652d0828600282c8e967mbansal 3641a2e9735136f372de95652d0828600282c8e967mbansal for (int ii = 0; ii < height; ii++) { 3741a2e9735136f372de95652d0828600282c8e967mbansal for (int ij = 0; ij < width; ij++) { 3841a2e9735136f372de95652d0828600282c8e967mbansal r = (*image++); 3941a2e9735136f372de95652d0828600282c8e967mbansal g = (*image++); 4041a2e9735136f372de95652d0828600282c8e967mbansal b = (*image++); 4141a2e9735136f372de95652d0828600282c8e967mbansal a = (*image++); 4241a2e9735136f372de95652d0828600282c8e967mbansal 4341a2e9735136f372de95652d0828600282c8e967mbansal if (r < 0) r = 0; 4441a2e9735136f372de95652d0828600282c8e967mbansal if (r > 255) r = 255; 4541a2e9735136f372de95652d0828600282c8e967mbansal if (g < 0) g = 0; 4641a2e9735136f372de95652d0828600282c8e967mbansal if (g > 255) g = 255; 4741a2e9735136f372de95652d0828600282c8e967mbansal if (b < 0) b = 0; 4841a2e9735136f372de95652d0828600282c8e967mbansal if (b > 255) b = 255; 4941a2e9735136f372de95652d0828600282c8e967mbansal 5041a2e9735136f372de95652d0828600282c8e967mbansal int val = (int) (REDY * r + GREENY * g + BLUEY * b) / 1000 + 16; 5141a2e9735136f372de95652d0828600282c8e967mbansal if (val < 0) val = 0; 5241a2e9735136f372de95652d0828600282c8e967mbansal if (val > 255) val = 255; 5341a2e9735136f372de95652d0828600282c8e967mbansal *(yimg) = val; 5441a2e9735136f372de95652d0828600282c8e967mbansal 5541a2e9735136f372de95652d0828600282c8e967mbansal val = (int) (REDV * r - GREENV * g - BLUEV * b) / 1000 + 128; 5641a2e9735136f372de95652d0828600282c8e967mbansal if (val < 0) val = 0; 5741a2e9735136f372de95652d0828600282c8e967mbansal if (val > 255) val = 255; 5841a2e9735136f372de95652d0828600282c8e967mbansal *(vimg) = val; 5941a2e9735136f372de95652d0828600282c8e967mbansal 6041a2e9735136f372de95652d0828600282c8e967mbansal val = (int) (-REDU * r - GREENU * g + BLUEU * b) / 1000 + 128; 6141a2e9735136f372de95652d0828600282c8e967mbansal if (val < 0) val = 0; 6241a2e9735136f372de95652d0828600282c8e967mbansal if (val > 255) val = 255; 6341a2e9735136f372de95652d0828600282c8e967mbansal *(uimg) = val; 6441a2e9735136f372de95652d0828600282c8e967mbansal 6541a2e9735136f372de95652d0828600282c8e967mbansal yimg++; 6641a2e9735136f372de95652d0828600282c8e967mbansal uimg++; 6741a2e9735136f372de95652d0828600282c8e967mbansal vimg++; 6841a2e9735136f372de95652d0828600282c8e967mbansal } 6941a2e9735136f372de95652d0828600282c8e967mbansal } 7041a2e9735136f372de95652d0828600282c8e967mbansal} 7141a2e9735136f372de95652d0828600282c8e967mbansal 7241a2e9735136f372de95652d0828600282c8e967mbansal 73e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::rgb2yvu(ImageType out, ImageType in, int width, int height) 74e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 75e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int r,g,b; 76e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType yimg = out; 77e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType vimg = yimg + width*height; 78e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType uimg = vimg + width*height; 79e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType image = in; 80e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 81e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int ii = 0; ii < height; ii++) { 82e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int ij = 0; ij < width; ij++) { 83e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen r = (*image++); 84e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen g = (*image++); 85e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen b = (*image++); 86e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 87e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r < 0) r = 0; 88e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r > 255) r = 255; 89e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g < 0) g = 0; 90e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g > 255) g = 255; 91e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b < 0) b = 0; 92e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b > 255) b = 255; 93e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 94e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int val = (int) (REDY * r + GREENY * g + BLUEY * b) / 1000 + 16; 95e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (val < 0) val = 0; 96e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (val > 255) val = 255; 97e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(yimg) = val; 98e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 99e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen val = (int) (REDV * r - GREENV * g - BLUEV * b) / 1000 + 128; 100e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (val < 0) val = 0; 101e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (val > 255) val = 255; 102e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(vimg) = val; 103e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 104e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen val = (int) (-REDU * r - GREENU * g + BLUEU * b) / 1000 + 128; 105e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (val < 0) val = 0; 106e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (val > 255) val = 255; 107e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(uimg) = val; 108e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 109e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yimg++; 110e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen uimg++; 111e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen vimg++; 112e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 113e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 114e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 115e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 116e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType ImageUtils::rgb2gray(ImageType in, int width, int height) 117e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 118e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int r,g,b, nr, ng, nb, val; 119e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType gray = NULL; 120e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType image = in; 121e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType out = ImageUtils::allocateImage(width, height, 1); 122e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType outCopy = out; 123e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 124e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int ii = 0; ii < height; ii++) { 125e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int ij = 0; ij < width; ij++) { 126e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen r = (*image++); 127e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen g = (*image++); 128e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen b = (*image++); 129e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 130e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r < 0) r = 0; 131e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r > 255) r = 255; 132e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g < 0) g = 0; 133e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g > 255) g = 255; 134e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b < 0) b = 0; 135e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b > 255) b = 255; 136e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 137e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen (*outCopy) = ( 0.3*r + 0.59*g + 0.11*b); 138e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 139e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen outCopy++; 140e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 141e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 142e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 143e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return out; 144e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 145e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 146e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType ImageUtils::rgb2gray(ImageType out, ImageType in, int width, int height) 147e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 148e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int r,g,b, nr, ng, nb, val; 149e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType gray = out; 150e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType image = in; 151e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType outCopy = out; 152e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 153e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int ii = 0; ii < height; ii++) { 154e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int ij = 0; ij < width; ij++) { 155e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen r = (*image++); 156e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen g = (*image++); 157e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen b = (*image++); 158e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 159e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r < 0) r = 0; 160e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r > 255) r = 255; 161e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g < 0) g = 0; 162e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g > 255) g = 255; 163e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b < 0) b = 0; 164e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b > 255) b = 255; 165e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 166e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen (*outCopy) = ( 0.3*r + 0.59*g + 0.11*b); 167e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 168e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen outCopy++; 169e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 170e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 171e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 172e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return out; 173e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 174e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 175e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 176e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType *ImageUtils::imageTypeToRowPointers(ImageType in, int width, int height) 177e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 178e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int i; 179e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int m_h = height; 180e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int m_w = width; 181e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 182e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType *m_rows = new ImageType[m_h]; 183e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 184e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (i=0;i<m_h;i++) { 185e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen m_rows[i] = &in[(m_w)*i]; 186e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 187e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return m_rows; 188e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 189e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 190e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::yvu2rgb(ImageType out, ImageType in, int width, int height) 191e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 192e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int y,v,u, r, g, b; 193e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *yimg = in; 194e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *vimg = yimg + width*height; 195e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *uimg = vimg + width*height; 196e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *image = out; 197e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 198e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int i = 0; i < height; i++) { 199e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int j = 0; j < width; j++) { 200e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 201e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen y = (*yimg); 202e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen v = (*vimg); 203e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen u = (*uimg); 204e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 205e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (y < 0) y = 0; 206e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (y > 255) y = 255; 207e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (u < 0) u = 0; 208e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (u > 255) u = 255; 209e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (v < 0) v = 0; 210e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (v > 255) v = 255; 211e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 212e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen b = (int) ( 1.164*(y - 16) + 2.018*(u-128)); 213e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen g = (int) ( 1.164*(y - 16) - 0.813*(v-128) - 0.391*(u-128)); 214e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen r = (int) ( 1.164*(y - 16) + 1.596*(v-128)); 215e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 216e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r < 0) r = 0; 217e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r > 255) r = 255; 218e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g < 0) g = 0; 219e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g > 255) g = 255; 220e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b < 0) b = 0; 221e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b > 255) b = 255; 222e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 223e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(image++) = r; 224e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(image++) = g; 225e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(image++) = b; 226e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 227e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yimg++; 228e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen uimg++; 229e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen vimg++; 230e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 231e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 232e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 233e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 234e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 235e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::yvu2bgr(ImageType out, ImageType in, int width, int height) 236e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 237e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int y,v,u, r, g, b; 238e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *yimg = in; 239e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *vimg = yimg + width*height; 240e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *uimg = vimg + width*height; 241e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *image = out; 242e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 243e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int i = 0; i < height; i++) { 244e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (int j = 0; j < width; j++) { 245e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 246e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen y = (*yimg); 247e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen v = (*vimg); 248e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen u = (*uimg); 249e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 250e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (y < 0) y = 0; 251e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (y > 255) y = 255; 252e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (u < 0) u = 0; 253e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (u > 255) u = 255; 254e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (v < 0) v = 0; 255e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (v > 255) v = 255; 256e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 257e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen b = (int) ( 1.164*(y - 16) + 2.018*(u-128)); 258e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen g = (int) ( 1.164*(y - 16) - 0.813*(v-128) - 0.391*(u-128)); 259e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen r = (int) ( 1.164*(y - 16) + 1.596*(v-128)); 260e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 261e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r < 0) r = 0; 262e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (r > 255) r = 255; 263e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g < 0) g = 0; 264e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (g > 255) g = 255; 265e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b < 0) b = 0; 266e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (b > 255) b = 255; 267e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 268e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(image++) = b; 269e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(image++) = g; 270e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *(image++) = r; 271e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 272e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yimg++; 273e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen uimg++; 274e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen vimg++; 275e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 276e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 277e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 278e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 279e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 280e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 281e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType ImageUtils::readBinaryPPM(const char *filename, int &width, int &height) 282e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 283e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 284e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen FILE *imgin = NULL; 285e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int mval=0, format=0, eret; 286e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ImageType ret = IMAGE_TYPE_NOIMAGE; 287e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 288e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen imgin = fopen(filename, "r"); 289e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (imgin == NULL) { 290e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fprintf(stderr, "Error: Filename %s not found\n", filename); 291e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return ret; 292e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 293e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 294e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen eret = fscanf(imgin, "P%d\n", &format); 295e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (format != 6) { 296e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fprintf(stderr, "Error: readBinaryPPM only supports PPM format (P6)\n"); 297e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return ret; 298e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 299e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 300e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen eret = fscanf(imgin, "%d %d\n", &width, &height); 301e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen eret = fscanf(imgin, "%d\n", &mval); 302e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen ret = allocateImage(width, height, IMAGE_TYPE_NUM_CHANNELS); 303e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen eret = fread(ret, sizeof(ImageTypeBase), IMAGE_TYPE_NUM_CHANNELS*width*height, imgin); 304e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 305e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fclose(imgin); 306e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 307e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return ret; 308e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 309e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 310e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 311e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::writeBinaryPPM(ImageType image, const char *filename, int width, int height, int numChannels) 312e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 313e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen FILE *imgout = fopen(filename, "w"); 314e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 315e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (imgout == NULL) { 316e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fprintf(stderr, "Error: Filename %s could not be opened for writing\n", filename); 317e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return; 318e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 319e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 320e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (numChannels == 3) { 321e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fprintf(imgout, "P6\n%d %d\n255\n", width, height); 322e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } else if (numChannels == 1) { 323e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fprintf(imgout, "P5\n%d %d\n255\n", width, height); 324e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } else { 325e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fprintf(stderr, "Error: writeBinaryPPM: Unsupported number of channels\n"); 326e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 327e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fwrite(image, sizeof(ImageTypeBase), numChannels*width*height, imgout); 328e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 329e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen fclose(imgout); 330e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 331e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 332e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 333e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType ImageUtils::allocateImage(int width, int height, int numChannels, short int border) 334e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 335e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int overallocation = 256; 336e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return (ImageType) calloc(width*height*numChannels+overallocation, sizeof(ImageTypeBase)); 337e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 338e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 339e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 340e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::freeImage(ImageType image) 341e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 342e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen free(image); 343e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 344e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 345e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 346e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// allocation of one color image used for tmp buffers, etc. 347e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// format of contiguous memory block: 348e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// YUVInfo struct (type + BimageInfo for Y,U, and V), 349e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// Y row pointers 350e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// U row pointers 351e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// V row pointers 352e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// Y image pixels 353e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// U image pixels 354e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// V image pixels 355e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenYUVinfo *YUVinfo::allocateImage(unsigned short width, unsigned short height) 356e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 357e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned short heightUV, widthUV; 358e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 359e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen widthUV = width; 360e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen heightUV = height; 361e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 362e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen // figure out how much space to hold all pixels... 36389b9c07b5bbcc2de25dd5f61c28de4575b4df996Wei-Ta Chen int size = ((width * height * 3) + 8); 364e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char *position = 0; 365e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 366e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen // VC 8 does not like calling free on yuv->Y.ptr since it is in 367e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen // the middle of a block. So rearrange the memory layout so after 368e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen // calling mapYUVInforToImage yuv->Y.ptr points to the begginning 369e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen // of the calloc'ed block. 370e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen YUVinfo *yuv = (YUVinfo *) calloc(sizeof(YUVinfo), 1); 371e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (yuv) { 372e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yuv->Y.width = yuv->Y.pitch = width; 373e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yuv->Y.height = height; 374e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yuv->Y.border = yuv->U.border = yuv->V.border = (unsigned short) 0; 375e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yuv->U.width = yuv->U.pitch = yuv->V.width = yuv->V.pitch = widthUV; 376e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yuv->U.height = yuv->V.height = heightUV; 377e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 378e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char* block = (unsigned char*) calloc( 379e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen sizeof(unsigned char *) * (height + heightUV + heightUV) + 380e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen sizeof(unsigned char) * size, 1); 381e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 382e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen position = block; 383e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen unsigned char **y = (unsigned char **) (block + size); 384e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 385e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen /* Initialize and assign row pointers */ 386e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yuv->Y.ptr = y; 387e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yuv->V.ptr = &y[height]; 388e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen yuv->U.ptr = &y[height + heightUV]; 389e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen } 390e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen if (size) 391e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen mapYUVInfoToImage(yuv, position); 392e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return yuv; 393e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 394e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 395e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// wrap YUVInfo row pointers around 3 contiguous image (color component) planes. 396e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// position = starting pixel in image. 397e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid YUVinfo::mapYUVInfoToImage(YUVinfo *img, unsigned char *position) 398e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{ 399e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen int i; 400e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (i = 0; i < img->Y.height; i++, position += img->Y.width) 401e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen img->Y.ptr[i] = position; 402e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (i = 0; i < img->V.height; i++, position += img->V.width) 403e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen img->V.ptr[i] = position; 404e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen for (i = 0; i < img->U.height; i++, position += img->U.width) 405e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen img->U.ptr[i] = position; 406e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen} 407e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 408e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen 409