diff options
Diffstat (limited to 'jni/feature_mos/src/mosaic/ImageUtils.cpp')
-rw-r--r-- | jni/feature_mos/src/mosaic/ImageUtils.cpp | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/jni/feature_mos/src/mosaic/ImageUtils.cpp b/jni/feature_mos/src/mosaic/ImageUtils.cpp new file mode 100644 index 0000000..792b90d --- /dev/null +++ b/jni/feature_mos/src/mosaic/ImageUtils.cpp @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/////////////////////////////////////////////////// +// ImageUtils.cpp +// $Id: ImageUtils.cpp,v 1.12 2011/06/17 13:35:48 mbansal Exp $ + + +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> + +#include "ImageUtils.h" + +void ImageUtils::rgb2yvu(ImageType out, ImageType in, int width, int height) +{ + int r,g,b; + ImageType yimg = out; + ImageType vimg = yimg + width*height; + ImageType uimg = vimg + width*height; + ImageType image = in; + + for (int ii = 0; ii < height; ii++) { + for (int ij = 0; ij < width; ij++) { + r = (*image++); + g = (*image++); + b = (*image++); + + if (r < 0) r = 0; + if (r > 255) r = 255; + if (g < 0) g = 0; + if (g > 255) g = 255; + if (b < 0) b = 0; + if (b > 255) b = 255; + + int val = (int) (REDY * r + GREENY * g + BLUEY * b) / 1000 + 16; + if (val < 0) val = 0; + if (val > 255) val = 255; + *(yimg) = val; + + val = (int) (REDV * r - GREENV * g - BLUEV * b) / 1000 + 128; + if (val < 0) val = 0; + if (val > 255) val = 255; + *(vimg) = val; + + val = (int) (-REDU * r - GREENU * g + BLUEU * b) / 1000 + 128; + if (val < 0) val = 0; + if (val > 255) val = 255; + *(uimg) = val; + + yimg++; + uimg++; + vimg++; + } + } +} + +ImageType ImageUtils::rgb2gray(ImageType in, int width, int height) +{ + int r,g,b, nr, ng, nb, val; + ImageType gray = NULL; + ImageType image = in; + ImageType out = ImageUtils::allocateImage(width, height, 1); + ImageType outCopy = out; + + for (int ii = 0; ii < height; ii++) { + for (int ij = 0; ij < width; ij++) { + r = (*image++); + g = (*image++); + b = (*image++); + + if (r < 0) r = 0; + if (r > 255) r = 255; + if (g < 0) g = 0; + if (g > 255) g = 255; + if (b < 0) b = 0; + if (b > 255) b = 255; + + (*outCopy) = ( 0.3*r + 0.59*g + 0.11*b); + + outCopy++; + } + } + + return out; +} + +ImageType ImageUtils::rgb2gray(ImageType out, ImageType in, int width, int height) +{ + int r,g,b, nr, ng, nb, val; + ImageType gray = out; + ImageType image = in; + ImageType outCopy = out; + + for (int ii = 0; ii < height; ii++) { + for (int ij = 0; ij < width; ij++) { + r = (*image++); + g = (*image++); + b = (*image++); + + if (r < 0) r = 0; + if (r > 255) r = 255; + if (g < 0) g = 0; + if (g > 255) g = 255; + if (b < 0) b = 0; + if (b > 255) b = 255; + + (*outCopy) = ( 0.3*r + 0.59*g + 0.11*b); + + outCopy++; + } + } + + return out; + +} + +ImageType *ImageUtils::imageTypeToRowPointers(ImageType in, int width, int height) +{ + int i; + int m_h = height; + int m_w = width; + + ImageType *m_rows = new ImageType[m_h]; + + for (i=0;i<m_h;i++) { + m_rows[i] = &in[(m_w)*i]; + } + return m_rows; +} + +void ImageUtils::yvu2rgb(ImageType out, ImageType in, int width, int height) +{ + int y,v,u, r, g, b; + unsigned char *yimg = in; + unsigned char *vimg = yimg + width*height; + unsigned char *uimg = vimg + width*height; + unsigned char *image = out; + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + + y = (*yimg); + v = (*vimg); + u = (*uimg); + + if (y < 0) y = 0; + if (y > 255) y = 255; + if (u < 0) u = 0; + if (u > 255) u = 255; + if (v < 0) v = 0; + if (v > 255) v = 255; + + b = (int) ( 1.164*(y - 16) + 2.018*(u-128)); + g = (int) ( 1.164*(y - 16) - 0.813*(v-128) - 0.391*(u-128)); + r = (int) ( 1.164*(y - 16) + 1.596*(v-128)); + + if (r < 0) r = 0; + if (r > 255) r = 255; + if (g < 0) g = 0; + if (g > 255) g = 255; + if (b < 0) b = 0; + if (b > 255) b = 255; + + *(image++) = r; + *(image++) = g; + *(image++) = b; + + yimg++; + uimg++; + vimg++; + + } + } +} + +void ImageUtils::yvu2bgr(ImageType out, ImageType in, int width, int height) +{ + int y,v,u, r, g, b; + unsigned char *yimg = in; + unsigned char *vimg = yimg + width*height; + unsigned char *uimg = vimg + width*height; + unsigned char *image = out; + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + + y = (*yimg); + v = (*vimg); + u = (*uimg); + + if (y < 0) y = 0; + if (y > 255) y = 255; + if (u < 0) u = 0; + if (u > 255) u = 255; + if (v < 0) v = 0; + if (v > 255) v = 255; + + b = (int) ( 1.164*(y - 16) + 2.018*(u-128)); + g = (int) ( 1.164*(y - 16) - 0.813*(v-128) - 0.391*(u-128)); + r = (int) ( 1.164*(y - 16) + 1.596*(v-128)); + + if (r < 0) r = 0; + if (r > 255) r = 255; + if (g < 0) g = 0; + if (g > 255) g = 255; + if (b < 0) b = 0; + if (b > 255) b = 255; + + *(image++) = b; + *(image++) = g; + *(image++) = r; + + yimg++; + uimg++; + vimg++; + + } + } +} + + +ImageType ImageUtils::readBinaryPPM(const char *filename, int &width, int &height) +{ + + FILE *imgin = NULL; + int mval=0, format=0, eret; + ImageType ret = IMAGE_TYPE_NOIMAGE; + + imgin = fopen(filename, "r"); + if (imgin == NULL) { + fprintf(stderr, "Error: Filename %s not found\n", filename); + return ret; + } + + eret = fscanf(imgin, "P%d\n", &format); + if (format != 6) { + fprintf(stderr, "Error: readBinaryPPM only supports PPM format (P6)\n"); + return ret; + } + + eret = fscanf(imgin, "%d %d\n", &width, &height); + eret = fscanf(imgin, "%d\n", &mval); + ret = allocateImage(width, height, IMAGE_TYPE_NUM_CHANNELS); + eret = fread(ret, sizeof(ImageTypeBase), IMAGE_TYPE_NUM_CHANNELS*width*height, imgin); + + fclose(imgin); + + return ret; + +} + +void ImageUtils::writeBinaryPPM(ImageType image, const char *filename, int width, int height, int numChannels) +{ + FILE *imgout = fopen(filename, "w"); + + if (imgout == NULL) { + fprintf(stderr, "Error: Filename %s could not be opened for writing\n", filename); + return; + } + + if (numChannels == 3) { + fprintf(imgout, "P6\n%d %d\n255\n", width, height); + } else if (numChannels == 1) { + fprintf(imgout, "P5\n%d %d\n255\n", width, height); + } else { + fprintf(stderr, "Error: writeBinaryPPM: Unsupported number of channels\n"); + } + fwrite(image, sizeof(ImageTypeBase), numChannels*width*height, imgout); + + fclose(imgout); + +} + +ImageType ImageUtils::allocateImage(int width, int height, int numChannels, short int border) +{ + int overallocation = 256; + return (ImageType) calloc(width*height*numChannels+overallocation, sizeof(ImageTypeBase)); +} + + +void ImageUtils::freeImage(ImageType image) +{ + free(image); +} + + +// allocation of one color image used for tmp buffers, etc. +// format of contiguous memory block: +// YUVInfo struct (type + BimageInfo for Y,U, and V), +// Y row pointers +// U row pointers +// V row pointers +// Y image pixels +// U image pixels +// V image pixels +YUVinfo *YUVinfo::allocateImage(unsigned short width, unsigned short height) +{ + unsigned short heightUV, widthUV; + + widthUV = width; + heightUV = height; + + // figure out how much space to hold all pixels... + int size = (((width * height * 32) >> 3) + 8); + unsigned char *position = 0; + + // VC 8 does not like calling free on yuv->Y.ptr since it is in + // the middle of a block. So rearrange the memory layout so after + // calling mapYUVInforToImage yuv->Y.ptr points to the begginning + // of the calloc'ed block. + YUVinfo *yuv = (YUVinfo *) calloc(sizeof(YUVinfo), 1); + if (yuv) { + yuv->Y.width = yuv->Y.pitch = width; + yuv->Y.height = height; + yuv->Y.border = yuv->U.border = yuv->V.border = (unsigned short) 0; + yuv->U.width = yuv->U.pitch = yuv->V.width = yuv->V.pitch = widthUV; + yuv->U.height = yuv->V.height = heightUV; + + unsigned char* block = (unsigned char*) calloc( + sizeof(unsigned char *) * (height + heightUV + heightUV) + + sizeof(unsigned char) * size, 1); + + position = block; + unsigned char **y = (unsigned char **) (block + size); + + /* Initialize and assign row pointers */ + yuv->Y.ptr = y; + yuv->V.ptr = &y[height]; + yuv->U.ptr = &y[height + heightUV]; + } + if (size) + mapYUVInfoToImage(yuv, position); + return yuv; +} + +// wrap YUVInfo row pointers around 3 contiguous image (color component) planes. +// position = starting pixel in image. +void YUVinfo::mapYUVInfoToImage(YUVinfo *img, unsigned char *position) +{ + int i; + for (i = 0; i < img->Y.height; i++, position += img->Y.width) + img->Y.ptr[i] = position; + for (i = 0; i < img->V.height; i++, position += img->V.width) + img->V.ptr[i] = position; + for (i = 0; i < img->U.height; i++, position += img->U.width) + img->U.ptr[i] = position; +} + + |