ImageUtils.cpp revision e295e32b68cf04f0d99138bf4a6d25555f3aef99
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
28e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::rgb2yvu(ImageType out, ImageType in, int width, int height)
29e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
30e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int r,g,b;
31e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType yimg = out;
32e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType vimg = yimg + width*height;
33e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType uimg = vimg + width*height;
34e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType image = in;
35e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
36e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for (int ii = 0; ii < height; ii++) {
37e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for (int ij = 0; ij < width; ij++) {
38e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      r = (*image++);
39e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      g = (*image++);
40e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      b = (*image++);
41e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
42e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (r < 0) r = 0;
43e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (r > 255) r = 255;
44e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (g < 0) g = 0;
45e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (g > 255) g = 255;
46e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (b < 0) b = 0;
47e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (b > 255) b = 255;
48e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
49e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      int val = (int) (REDY * r + GREENY * g + BLUEY * b) / 1000 + 16;
50e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (val < 0) val = 0;
51e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (val > 255) val = 255;
52e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      *(yimg) = val;
53e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
54e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      val = (int) (REDV * r - GREENV * g - BLUEV * b) / 1000 + 128;
55e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (val < 0) val = 0;
56e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (val > 255) val = 255;
57e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      *(vimg) = val;
58e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
59e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      val = (int) (-REDU * r - GREENU * g + BLUEU * b) / 1000 + 128;
60e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (val < 0) val = 0;
61e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (val > 255) val = 255;
62e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      *(uimg) = val;
63e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
64e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      yimg++;
65e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      uimg++;
66e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      vimg++;
67e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    }
68e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
69e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
70e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
71e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType ImageUtils::rgb2gray(ImageType in, int width, int height)
72e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
73e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int r,g,b, nr, ng, nb, val;
74e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType gray = NULL;
75e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType image = in;
76e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType out = ImageUtils::allocateImage(width, height, 1);
77e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType outCopy = out;
78e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
79e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for (int ii = 0; ii < height; ii++) {
80e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for (int ij = 0; ij < width; ij++) {
81e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      r = (*image++);
82e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      g = (*image++);
83e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      b = (*image++);
84e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
85e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (r < 0) r = 0;
86e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (r > 255) r = 255;
87e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (g < 0) g = 0;
88e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (g > 255) g = 255;
89e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (b < 0) b = 0;
90e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (b > 255) b = 255;
91e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
92e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      (*outCopy) = ( 0.3*r + 0.59*g + 0.11*b);
93e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
94e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      outCopy++;
95e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    }
96e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
97e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
98e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return out;
99e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
100e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
101e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType ImageUtils::rgb2gray(ImageType out, ImageType in, int width, int height)
102e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
103e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int r,g,b, nr, ng, nb, val;
104e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType gray = out;
105e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType image = in;
106e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType outCopy = out;
107e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
108e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for (int ii = 0; ii < height; ii++) {
109e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for (int ij = 0; ij < width; ij++) {
110e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      r = (*image++);
111e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      g = (*image++);
112e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      b = (*image++);
113e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
114e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (r < 0) r = 0;
115e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (r > 255) r = 255;
116e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (g < 0) g = 0;
117e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (g > 255) g = 255;
118e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (b < 0) b = 0;
119e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (b > 255) b = 255;
120e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
121e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      (*outCopy) = ( 0.3*r + 0.59*g + 0.11*b);
122e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
123e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      outCopy++;
124e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    }
125e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
126e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
127e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return out;
128e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
129e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
130e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
131e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType *ImageUtils::imageTypeToRowPointers(ImageType in, int width, int height)
132e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
133e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int i;
134e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int m_h = height;
135e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int m_w = width;
136e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
137e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType *m_rows = new ImageType[m_h];
138e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
139e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for (i=0;i<m_h;i++) {
140e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    m_rows[i] = &in[(m_w)*i];
141e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
142e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return m_rows;
143e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
144e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
145e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::yvu2rgb(ImageType out, ImageType in, int width, int height)
146e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
147e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int y,v,u, r, g, b;
148e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  unsigned char *yimg = in;
149e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  unsigned char *vimg = yimg + width*height;
150e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  unsigned char *uimg = vimg + width*height;
151e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  unsigned char *image = out;
152e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
153e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  for (int i = 0; i < height; i++) {
154e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for (int j = 0; j < width; j++) {
155e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
156e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      y = (*yimg);
157e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      v = (*vimg);
158e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      u = (*uimg);
159e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
160e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (y < 0) y = 0;
161e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (y > 255) y = 255;
162e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (u < 0) u = 0;
163e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (u > 255) u = 255;
164e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (v < 0) v = 0;
165e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (v > 255) v = 255;
166e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
167e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      b = (int) ( 1.164*(y - 16) + 2.018*(u-128));
168e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      g = (int) ( 1.164*(y - 16) - 0.813*(v-128) - 0.391*(u-128));
169e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      r = (int) ( 1.164*(y - 16) + 1.596*(v-128));
170e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
171e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (r < 0) r = 0;
172e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (r > 255) r = 255;
173e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (g < 0) g = 0;
174e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (g > 255) g = 255;
175e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (b < 0) b = 0;
176e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      if (b > 255) b = 255;
177e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
178e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      *(image++) = r;
179e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      *(image++) = g;
180e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      *(image++) = b;
181e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
182e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      yimg++;
183e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      uimg++;
184e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      vimg++;
185e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
186e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    }
187e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
188e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
189e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
190e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::yvu2bgr(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++) = b;
224e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      *(image++) = g;
225e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen      *(image++) = r;
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 Chen
236e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType ImageUtils::readBinaryPPM(const char *filename, int &width, int &height)
237e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
238e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
239e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  FILE *imgin = NULL;
240e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int mval=0, format=0, eret;
241e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType ret = IMAGE_TYPE_NOIMAGE;
242e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
243e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  imgin = fopen(filename, "r");
244e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (imgin == NULL) {
245e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    fprintf(stderr, "Error: Filename %s not found\n", filename);
246e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return ret;
247e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
248e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
249e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  eret = fscanf(imgin, "P%d\n", &format);
250e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (format != 6) {
251e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    fprintf(stderr, "Error: readBinaryPPM only supports PPM format (P6)\n");
252e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return ret;
253e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
254e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
255e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  eret = fscanf(imgin, "%d %d\n", &width, &height);
256e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  eret = fscanf(imgin, "%d\n", &mval);
257e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ret  = allocateImage(width, height, IMAGE_TYPE_NUM_CHANNELS);
258e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  eret = fread(ret, sizeof(ImageTypeBase), IMAGE_TYPE_NUM_CHANNELS*width*height, imgin);
259e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
260e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  fclose(imgin);
261e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
262e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  return ret;
263e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
264e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
265e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
266e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::writeBinaryPPM(ImageType image, const char *filename, int width, int height, int numChannels)
267e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
268e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  FILE *imgout = fopen(filename, "w");
269e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
270e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (imgout == NULL) {
271e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    fprintf(stderr, "Error: Filename %s could not be opened for writing\n", filename);
272e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return;
273e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
274e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
275e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  if (numChannels == 3) {
276e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    fprintf(imgout, "P6\n%d %d\n255\n", width, height);
277e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  } else if (numChannels == 1) {
278e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    fprintf(imgout, "P5\n%d %d\n255\n", width, height);
279e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  } else {
280e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    fprintf(stderr, "Error: writeBinaryPPM: Unsupported number of channels\n");
281e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  }
282e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  fwrite(image, sizeof(ImageTypeBase), numChannels*width*height, imgout);
283e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
284e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  fclose(imgout);
285e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
286e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
287e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
288e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenImageType ImageUtils::allocateImage(int width, int height, int numChannels, short int border)
289e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
290e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int overallocation = 256;
291e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen return (ImageType) calloc(width*height*numChannels+overallocation, sizeof(ImageTypeBase));
292e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
293e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
294e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
295e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid ImageUtils::freeImage(ImageType image)
296e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
297e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  free(image);
298e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
299e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
300e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
301e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// allocation of one color image used for tmp buffers, etc.
302e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// format of contiguous memory block:
303e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen//    YUVInfo struct (type + BimageInfo for Y,U, and V),
304e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen//    Y row pointers
305e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen//    U row pointers
306e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen//    V row pointers
307e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen//    Y image pixels
308e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen//    U image pixels
309e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen//    V image pixels
310e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta ChenYUVinfo *YUVinfo::allocateImage(unsigned short width, unsigned short height)
311e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
312e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    unsigned short heightUV, widthUV;
313e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
314e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    widthUV = width;
315e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    heightUV = height;
316e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
317e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // figure out how much space to hold all pixels...
318e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int size = (((width * height * 32) >> 3) + 8);
319e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    unsigned char *position = 0;
320e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
321e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // VC 8 does not like calling free on yuv->Y.ptr since it is in
322e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // the middle of a block.  So rearrange the memory layout so after
323e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // calling mapYUVInforToImage yuv->Y.ptr points to the begginning
324e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // of the calloc'ed block.
325e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    YUVinfo *yuv = (YUVinfo *) calloc(sizeof(YUVinfo), 1);
326e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    if (yuv) {
327e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        yuv->Y.width  = yuv->Y.pitch = width;
328e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        yuv->Y.height = height;
329e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        yuv->Y.border = yuv->U.border = yuv->V.border = (unsigned short) 0;
330e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        yuv->U.width  = yuv->U.pitch = yuv->V.width = yuv->V.pitch = widthUV;
331e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        yuv->U.height = yuv->V.height = heightUV;
332e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
333e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        unsigned char* block = (unsigned char*) calloc(
334e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen                sizeof(unsigned char *) * (height + heightUV + heightUV) +
335e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen                sizeof(unsigned char) * size, 1);
336e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
337e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        position = block;
338e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        unsigned char **y = (unsigned char **) (block + size);
339e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
340e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        /* Initialize and assign row pointers */
341e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        yuv->Y.ptr = y;
342e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        yuv->V.ptr = &y[height];
343e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        yuv->U.ptr = &y[height + heightUV];
344e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    }
345e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    if (size)
346e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        mapYUVInfoToImage(yuv, position);
347e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    return yuv;
348e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
349e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
350e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// wrap YUVInfo row pointers around 3 contiguous image (color component) planes.
351e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// position = starting pixel in image.
352e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenvoid YUVinfo::mapYUVInfoToImage(YUVinfo *img, unsigned char *position)
353e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
354e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int i;
355e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for (i = 0; i < img->Y.height; i++, position += img->Y.width)
356e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        img->Y.ptr[i] = position;
357e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for (i = 0; i < img->V.height; i++, position += img->V.width)
358e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        img->V.ptr[i] = position;
359e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    for (i = 0; i < img->U.height; i++, position += img->U.width)
360e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        img->U.ptr[i] = position;
361e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen}
362e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
363e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
364