summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authoryux@google.com <yux@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-22 18:40:05 +0000
committeryux@google.com <yux@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-22 18:40:05 +0000
commitfbe1347b202d9ed98d193305d37d765e3afd29be (patch)
treecee4f1bb2eebd2cb96272dcc24d58d3d71ba78cb /o3d
parent5fa8a7078cfd464446c0b347ee6617b6e3c98a11 (diff)
downloadchromium_src-fbe1347b202d9ed98d193305d37d765e3afd29be.zip
chromium_src-fbe1347b202d9ed98d193305d37d765e3afd29be.tar.gz
chromium_src-fbe1347b202d9ed98d193305d37d765e3afd29be.tar.bz2
Change bilinear interpolation to lanczos resampling,
and update related unit tests and selenium reference img. Review URL: http://codereview.chromium.org/159180 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21299 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/DEPS2
-rw-r--r--o3d/DEPS_gyp2
-rw-r--r--o3d/core/cross/bitmap.cc257
-rw-r--r--o3d/core/cross/bitmap.h908
-rw-r--r--o3d/core/cross/bitmap_test.cc76
-rw-r--r--o3d/core/cross/texture.cc26
6 files changed, 672 insertions, 599 deletions
diff --git a/o3d/DEPS b/o3d/DEPS
index 306a956..04f0d55 100644
--- a/o3d/DEPS
+++ b/o3d/DEPS
@@ -2,7 +2,7 @@ vars = {
"chromium_trunk":
"http://src.chromium.org/svn/trunk",
"nixysa_rev": "28",
- "o3d_code_rev": "100",
+ "o3d_code_rev": "101",
}
deps = {
diff --git a/o3d/DEPS_gyp b/o3d/DEPS_gyp
index f7b2829..2ea2108 100644
--- a/o3d/DEPS_gyp
+++ b/o3d/DEPS_gyp
@@ -3,7 +3,7 @@ vars = {
"http://src.chromium.org/svn/trunk",
"nixysa_rev": "28",
"chromium_rev": "19644",
- "o3d_code_rev": "97",
+ "o3d_code_rev": "101",
}
deps = {
diff --git a/o3d/core/cross/bitmap.cc b/o3d/core/cross/bitmap.cc
index 98863cf..6487fbd 100644
--- a/o3d/core/cross/bitmap.cc
+++ b/o3d/core/cross/bitmap.cc
@@ -54,6 +54,19 @@ using file_util::GetFileSize;
namespace {
static const double kEpsilon = 0.0001;
+static const double kPi = 3.14159265358979;
+static const int kFilterSize = 3;
+
+// utility function, round double numbers into 0 to 255 integers.
+uint8 Safe8Round(double f) {
+ f += 0.5;
+ if (f < 0.0) {
+ return 0;
+ } else if (!(f < 255.0)) {
+ return 255;
+ }
+ return static_cast<uint8>(f);
+}
} // anonymous namespace.
namespace o3d {
@@ -333,117 +346,147 @@ void Bitmap::DrawImage(Bitmap* src_img,
// crop part of image from src img, scale it in
// bilinear interpolation fashion, and paste it
// on dst img.
- BilinearInterpolateScale(src_img_data, src_x, src_y,
- src_width, src_height,
- src_img->width_, src_img->height_,
- dst_img_data, dst_x, dst_y,
- dst_width, dst_height,
- width_, height_, components);
+ LanczosScale(src_img_data, src_x, src_y,
+ src_width, src_height,
+ src_img->width_, src_img->height_,
+ dst_img_data, dst_x, dst_y,
+ dst_width, dst_height,
+ width_, height_, components);
+}
+
+void Bitmap::LanczosScale(const uint8* src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int src_img_width, int src_img_height,
+ uint8* dest,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int dest_img_width, int dest_img_height,
+ int components) {
+ // Scale the image horizontally to a temp buffer.
+ int temp_img_width = abs(dest_width);
+ int temp_img_height = abs(src_height);
+ int temp_width = dest_width;
+ int temp_height = src_height;
+ int temp_x = 0, temp_y = 0;
+ if (temp_width < 0)
+ temp_x = abs(temp_width) - 1;
+ if (temp_height < 0)
+ temp_y = abs(temp_height) - 1;
+
+ scoped_array<uint8> temp(new uint8[temp_img_width *
+ temp_img_height * components]);
+
+ LanczosResize1D(src, src_x, src_y, src_width, src_height,
+ src_img_width, src_img_height,
+ temp.get(), temp_x, temp_y, temp_width,
+ temp_img_width, temp_img_height, true, components);
+
+ // Scale the temp buffer vertically to get the final result.
+ LanczosResize1D(temp.get(), temp_x, temp_y, temp_height, temp_width,
+ temp_img_width, temp_img_height,
+ dest, dest_x, dest_y, dest_height,
+ dest_img_width, dest_img_height, false, components);
}
-// static utility function used by DrawImage in bitmap and textures.
-// in this function, positions are converted to 4th-quadrant, which
-// means origin locates left-up corner.
-void Bitmap::BilinearInterpolateScale(const uint8* src_img_data,
- int src_x, int src_y,
- int src_width, int src_height,
- int src_img_width, int src_img_height,
- uint8* dest_img_data,
- int dest_x, int dest_y,
- int dest_width, int dest_height,
- int dest_img_width, int dest_img_height,
- int components) {
- for (int i = 0; i < std::abs(dest_width); i++) {
- // x is the iterator of dest_width in dest_img.
- // change x to negative if dest_width is negative.
+void Bitmap::LanczosResize1D(const uint8* src, int src_x, int src_y,
+ int width, int height,
+ int src_bmp_width, int src_bmp_height,
+ uint8* out, int dest_x, int dest_y,
+ int nwidth,
+ int dest_bmp_width, int dest_bmp_height,
+ bool isWidth, int components) {
+ // calculate scale factor and init the weight array for lanczos filter.
+ float scale = fabs(static_cast<float>(width) / nwidth);
+ float support = kFilterSize * scale;
+ scoped_array<float> weight(new float[static_cast<int>(support * 2) + 4]);
+ // we assume width is the dimension we are scaling, and height stays
+ // the same.
+ for (int i = 0; i < abs(nwidth); ++i) {
+ // center is the corresponding coordinate of i in original img.
+ float center = (i + 0.5) * scale;
+ // boundary of weight array in original img.
+ int xmin = static_cast<int>(floor(center - support));
+ if (xmin < 0) xmin = 0;
+ int xmax = static_cast<int>(ceil(center + support));
+ if (xmax >= abs(width)) xmax = abs(width) - 1;
+
+ // fill up weight array by lanczos filter.
+ float wsum = 0.0;
+ for (int ox = xmin; ox <= xmax; ++ox) {
+ float wtemp;
+ float dx = ox + 0.5 - center;
+ // lanczos filter
+ if (dx <= -kFilterSize || dx >= kFilterSize) {
+ wtemp = 0.0;
+ } else if (dx == 0.0) {
+ wtemp = 1.0;
+ } else {
+ wtemp = kFilterSize * sin(kPi * dx) * sin(kPi / kFilterSize * dx) /
+ (kPi * kPi * dx * dx);
+ }
+
+ weight[ox - xmin] = wtemp;
+ wsum += wtemp;
+ }
+ int wcount = xmax - xmin + 1;
+
+ // Normalize the weights.
+ if (fabs(wsum) > kEpsilon) {
+ for (int k = 0; k < wcount; ++k) {
+ weight[k] /= wsum;
+ }
+ }
+ // Now that we've computed the filter weights for this x-position
+ // of the image, we can apply that filter to all pixels in that
+ // column.
+ // calculate coordinate in new img.
int x = i;
- if (dest_width < 0)
- x = -i;
-
- // calculate corresponding coordinate in src_img.
- double base_x = i * (std::abs(src_width) - 1) /
- static_cast<double>(std::abs(dest_width) - 1);
- // base_floor_x is the iterator of src_width in src_img.
- // change base_x to negative if src_width is negative.
- if (src_width < 0)
- base_x = -base_x;
- int base_floor_x = static_cast<int>(std::floor(base_x));
-
- for (int j = 0; j < std::abs(dest_height); j++) {
- // y is the iterator of dest_height in dest_img.
- // change y to negative if dest_height is negative.
- int y = j;
- if (dest_height < 0)
- y = -j;
-
- // calculate coresponding coordinate in src_img.
- double base_y = j * (std::abs(src_height) - 1) /
- static_cast<double>(std::abs(dest_height) - 1);
- // change base_y to negative if src_height is negative.
- if (src_height < 0)
- base_y = -base_y;
- int base_floor_y = static_cast<int>(std::floor(base_y));
-
- for (int c = 0; c < components; c++) {
- // if base_x and base_y are integers, which means this point
- // exists in src_img, just copy the original values.
- if (base_x - base_floor_x < kEpsilon &&
- base_y - base_floor_y < kEpsilon) {
- dest_img_data[((dest_img_height - (y + dest_y) - 1) *
- dest_img_width + dest_x + x) * components + c] =
- src_img_data[((src_img_height - (base_floor_y + src_y) - 1) *
- src_img_width + src_x + base_floor_x) * components + c];
- continue;
+ if (nwidth < 0)
+ x = -1 * x;
+ // lower bound of coordinate in original img.
+ if (width < 0)
+ xmin = -1 * xmin;
+ for (int j = 0; j < abs(height); ++j) {
+ // coordinate in height, same in src and dest img.
+ int base_y = j;
+ if (height < 0)
+ base_y = -1 * base_y;
+ // TODO(yux): fix the vertical flip problem and merge this if-else
+ // statement coz at that time, there would be no need to check
+ // which measure we are scaling.
+ if (isWidth) {
+ const uint8* inrow = src + ((src_bmp_height - (src_y + base_y) - 1) *
+ src_bmp_width + src_x + xmin) * components;
+ uint8* outpix = out + ((dest_bmp_height - (dest_y + base_y) - 1) *
+ dest_bmp_width + dest_x + x) * components;
+ int step = components;
+ if (width < 0)
+ step = -1 * step;
+ for (int b = 0; b < components; ++b) {
+ float sum = 0.0;
+ for (int k = 0, xk = b; k < wcount; ++k, xk += step)
+ sum += weight[k] * inrow[xk];
+
+ outpix[b] = Safe8Round(sum);
+ }
+ } else {
+ const uint8* inrow = src + (src_x + base_y + (src_bmp_height -
+ (src_y + xmin) - 1) * src_bmp_width) *
+ components;
+ uint8* outpix = out + (dest_x + base_y + (dest_bmp_height -
+ (dest_y + x) - 1) * dest_bmp_width) * components;
+
+ int step = src_bmp_width * components;
+ if (width < 0)
+ step = -1 * step;
+ for (int b = 0; b < components; ++b) {
+ float sum = 0.0;
+ for (int k = 0, xk = b; k < wcount; ++k, xk -= step)
+ sum += weight[k] * inrow[xk];
+
+ outpix[b] = Safe8Round(sum);
}
-
- // get four nearest neighbors of point (base_x, base_y) from src img.
- uint8 src_neighbor_11, src_neighbor_21,
- src_neighbor_12, src_neighbor_22;
- src_neighbor_11 = src_img_data[((src_img_height - (base_floor_y +
- src_y) - 1) * src_img_width + src_x +
- base_floor_x) * components + c];
- // if base_x exists in src img. set src_neighbor_21 to src_neighbor_11
- // so the interpolation result would remain src_neighbor_11.
- if (base_x - base_floor_x < kEpsilon)
- src_neighbor_21 = src_neighbor_11;
- else
- src_neighbor_21 = src_img_data[((src_img_height - (base_floor_y +
- src_y) - 1) * src_img_width + src_x +
- base_floor_x + 1) * components + c];
- // if base_y exists in src img. set src_neighbor_12 to src_neighbor_11
- // so the interpolation result would remain src_neighbor_11.
- if (base_y - base_floor_y < kEpsilon)
- src_neighbor_12 = src_neighbor_11;
- else
- src_neighbor_12 = src_img_data[((src_img_height - (base_floor_y +
- src_y) - 2) * src_img_width + src_x +
- base_floor_x) * components + c];
-
- if (base_x - base_floor_x < kEpsilon)
- src_neighbor_22 = src_neighbor_21;
- else if (base_y - base_floor_y < kEpsilon)
- src_neighbor_22 = src_neighbor_12;
- else
- src_neighbor_22 = src_img_data[((src_img_height - (base_floor_y +
- src_y) - 2) * src_img_width + src_x +
- base_floor_x + 1) * components + c];
-
- // calculate interpolated value.
- double interpolatedValue = (1 - (base_y - base_floor_y)) *
- ((base_x - base_floor_x) *
- src_neighbor_21 +
- (1 - (base_x - base_floor_x)) *
- src_neighbor_11) +
- (base_y - base_floor_y) *
- ((base_x - base_floor_x) *
- src_neighbor_22 +
- (1 - (base_x - base_floor_x)) *
- src_neighbor_12);
-
- // assign the nearest integer of interpolatedValue to dest_img_data.
- dest_img_data[((dest_img_height - (y + dest_y) - 1) * dest_img_width +
- dest_x + x) * components + c] =
- static_cast<uint8>(interpolatedValue + 0.5);
}
}
}
diff --git a/o3d/core/cross/bitmap.h b/o3d/core/cross/bitmap.h
index 8100b86..bebe6c6 100644
--- a/o3d/core/cross/bitmap.h
+++ b/o3d/core/cross/bitmap.h
@@ -1,439 +1,469 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-// This file contains the declaration of Bitmap helper class that can load
-// raw 24- and 32-bit bitmaps from popular image formats. The Bitmap class
-// also interprets the file format to record the correct OpenGL buffer format.
-//
-// Trying to keep this class independent from the OpenGL API in case they
-// need retargeting later on.
-
-#ifndef O3D_CORE_CROSS_BITMAP_H_
-#define O3D_CORE_CROSS_BITMAP_H_
-
-#include <stdlib.h>
-
-#include "base/cross/bits.h"
-#include "core/cross/types.h"
-#include "core/cross/texture.h"
-
-class FilePath;
-
-namespace o3d {
-
-class MemoryReadStream;
-class RawData;
-class Pack;
-
-// Bitmap provides an API for basic image operations on bitmap images,
-// including scale and crop. The contents of bitmap can be created from
-// a RawData object via LoadFromRawData(), and also can be transfered
-// to mip of a Texure2D or a specific face of TextureCUBE via methods
-// in Texture.
-
-class Bitmap : public ParamObject {
- public:
- typedef SmartPointer<Bitmap> Ref;
-
- explicit Bitmap(ServiceLocator* service_locator);
- virtual ~Bitmap() {}
-
- // We will fail to load images that are bigger than 4kx4k to avoid security
- // risks. GPUs don't usually support bigger sizes anyway.
- // The biggest bitmap buffer size with these dimensions is:
- // 4k x 4k x 4xsizeof(float) x6 x4/3 (x6 for cube maps, x4/3 for mipmaps)
- // That makes 2GB, representable in an unsigned int, so we will avoid wraps.
- static const unsigned int kMaxImageDimension = 4096;
- enum ImageFileType {
- UNKNOWN,
- TGA,
- JPEG,
- PNG,
- DDS,
- };
-
- static bool CheckImageDimensions(unsigned int width, unsigned int height) {
- return width > 0 && height > 0 &&
- width <= kMaxImageDimension && height < kMaxImageDimension;
- }
-
- // Creates a copy of a bitmap, copying the pixels as well.
- // Parameters:
- // source: the source bitmap.
- void CopyDeepFrom(const Bitmap &source) {
- Allocate(source.format_, source.width_, source.height_,
- source.num_mipmaps_, source.is_cubemap_);
- memcpy(image_data(), source.image_data(), GetTotalSize());
- }
-
- // Sets the bitmap parameters from another bitmap, stealing the pixel buffer
- // from the source bitmap.
- // Parameters:
- // source: the source bitmap.
- void SetFrom(Bitmap *source) {
- image_data_.reset();
- format_ = source->format_;
- width_ = source->width_;
- height_ = source->height_;
- num_mipmaps_ = source->num_mipmaps_;
- is_cubemap_ = source->is_cubemap_;
- image_data_.swap(source->image_data_);
- }
-
- // Allocates an uninitialized bitmap with specified parameters.
- // Parameters:
- // format: the format of the pixels.
- // width: the width of the base image.
- // height: the height of the base image.
- // num_mipmaps: the number of mip-maps.
- // cube_map: true if creating a cube map.
- void Allocate(Texture::Format format,
- unsigned int width,
- unsigned int height,
- unsigned int num_mipmaps,
- bool cube_map);
-
- // Allocates a bitmap with initialized parameters.
- // data is zero-initialized
- void AllocateData() {
- image_data_.reset(new unsigned char[GetTotalSize()]);
- memset(image_data_.get(), 0, GetTotalSize());
- }
-
- // Frees the data owned by the bitmap.
- void FreeData() {
- image_data_.reset(NULL);
- }
-
- // Gets the total size of the bitmap data, counting all faces and mip levels.
- unsigned int GetTotalSize() {
- return (is_cubemap_ ? 6 : 1) *
- GetMipChainSize(width_, height_, format_, num_mipmaps_);
- }
-
- // Computes the number of bytes of a texture pixel buffer.
- static unsigned int GetBufferSize(unsigned int width,
- unsigned int height,
- Texture::Format format);
-
- // Gets the image data for a given mip-map level and cube map face.
- // Parameters:
- // level: mip level to get.
- // face: face of cube to get. This parameter is ignored if
- // this bitmap is not a cube map.
- unsigned char *GetMipData(unsigned int level,
- TextureCUBE::CubeFace face) const;
-
- unsigned char *image_data() const { return image_data_.get(); }
- Texture::Format format() const { return format_; }
- unsigned int width() const { return width_; }
- unsigned int height() const { return height_; }
- unsigned int num_mipmaps() const { return num_mipmaps_; }
- bool is_cubemap() const { return is_cubemap_; }
-
- // Returns whether or not the dimensions of the bitmap are power-of-two.
- bool IsPOT() const {
- return ((width_ & (width_ - 1)) == 0) && ((height_ & (height_ - 1)) == 0);
- }
-
- void set_format(Texture::Format format) { format_ = format; }
- void set_width(unsigned int n) { width_ = n; }
- void set_height(unsigned int n) { height_ = n; }
- void set_num_mipmaps(unsigned int n) { num_mipmaps_ = n; }
- void set_is_cubemap(bool is_cubemap) { is_cubemap_ = is_cubemap; }
-
- // Loads a bitmap from a file.
- // Parameters:
- // filename: the name of the file to load.
- // file_type: the type of file to load. If UNKNOWN, the file type will be
- // determined from the filename extension, and if it is not a
- // known extension, all the loaders will be tried.
- // generate_mipmaps: whether or not to generate all the mip-map levels.
- bool LoadFromFile(const FilePath &filepath,
- ImageFileType file_type,
- bool generate_mipmaps);
-
- // Loads a bitmap from a RawData object.
- // Parameters:
- // raw_data: contains the bitmap data in one of the known formats
- // file_type: the format of the bitmap data. If UNKNOWN, the file type
- // will be determined from the extension from raw_data's uri
- // and if it is not a known extension, all the loaders will
- // be tried.
- // generate_mipmaps: whether or not to generate all the mip-map levels.
- bool LoadFromRawData(RawData *raw_data,
- ImageFileType file_type,
- bool generate_mipmaps);
-
- // Loads a bitmap from a MemoryReadStream.
- // Parameters:
- // stream: a stream for the bitmap data in one of the known formats
- // filename: a filename (or uri) of the original bitmap data
- // (may be an empty string)
- // file_type: the format of the bitmap data. If UNKNOWN, the file type
- // will be determined from the extension of |filename|
- // and if it is not a known extension, all the loaders
- // will be tried.
- // generate_mipmaps: whether or not to generate all the mip-map levels.
- bool LoadFromStream(MemoryReadStream *stream,
- const String &filename,
- ImageFileType file_type,
- bool generate_mipmaps);
-
- bool LoadFromPNGStream(MemoryReadStream *stream,
- const String &filename,
- bool generate_mipmaps);
-
- bool LoadFromTGAStream(MemoryReadStream *stream,
- const String &filename,
- bool generate_mipmaps);
-
- bool LoadFromDDSStream(MemoryReadStream *stream,
- const String &filename,
- bool generate_mipmaps);
-
- bool LoadFromJPEGStream(MemoryReadStream *stream,
- const String &filename,
- bool generate_mipmaps);
-
- // Saves to a PNG file. The image must be of the ARGB8 format, be a 2D image
- // with no mip-maps (only the base level).
- // Parameters:
- // filename: the name of the file to into.
- // Returns:
- // true if successful.
- bool SaveToPNGFile(const char* filename);
-
- // Checks that the alpha channel for the entire bitmap is 1.0
- bool CheckAlphaIsOne() const;
-
- // Copy pixels from source bitmap. Scales if the width and height of source
- // and dest do not match.
- // Parameters:
- // source_img: source bitmap which would be drawn.
- // source_x: x-coordinate of the starting pixel in the source image.
- // source_x: y-coordinate of the starting pixel in the source image.
- // source_width: width of the source image to draw.
- // source_height: Height of the source image to draw.
- // dest_x: x-coordinate of the starting pixel in the dest image.
- // dest_y: y-coordinate of the starting pixel in the dest image.
- // dest_width: width of the dest image to draw.
- // dest_height: height of the dest image to draw.
- void DrawImage(Bitmap* source_img, int source_x, int source_y,
- int source_width, int source_height,
- int dest_x, int dest_y,
- int dest_width, int dest_height);
-
- // Crop part of an image from src, scale it to an arbitrary size
- // and paste in dest image. Utility function for all DrawImage
- // function in bitmap and textures. Scale operation is based on
- // bilinear interpolation.
- // Note: this doesn't work for DXTC, or floating-point images.
- //
- // Parameters:
- // src: source image which would be copied from.
- // src_x: x-coordinate of the starting pixel in the src image.
- // src_y: y-coordinate of the starting pixel in the src image.
- // src_width: width of the part in src image to be croped.
- // src_height: height of the part in src image to be croped.
- // src_img_width: width of the src image.
- // src_img_height: height of the src image.
- // dest: dest image which would be copied to.
- // dest_x: x-coordinate of the starting pixel in the dest image.
- // dest_y: y-coordinate of the starting pixel in the dest image.
- // dest_width: width of the part in dest image to be pasted to.
- // dest_height: height of the part in dest image to be pasted to.
- // dest_img_width: width of the dest image.
- // dest_img_height: height of the src image.
- // component: size of each pixel in terms of array element.
- // Returns:
- // true if crop and scale succeeds.
- static void BilinearInterpolateScale(const uint8* src,
- int src_x, int src_y,
- int src_width, int src_height,
- int src_img_width, int src_img_height,
- uint8* dest,
- int dest_x, int dest_y,
- int dest_width, int dest_height,
- int dest_img_width, int dest_img_height,
- int component);
-
- // Detects the type of image file based on the filename.
- static ImageFileType GetFileTypeFromFilename(const char *filename);
- // Detects the type of image file based on the mime-type.
- static ImageFileType GetFileTypeFromMimeType(const char *mime_type);
-
- // Adds filler alpha byte (0xff) after every pixel. Assumes buffer was
- // allocated with enough storage)
- // can convert RGB -> RGBA, BGR -> BGRA, etc.
- static void XYZToXYZA(unsigned char *image_data, int pixel_count);
-
- // Swaps Red and Blue components in the image.
- static void RGBAToBGRA(unsigned char *image_data, int pixel_count);
-
- // Gets the number of mip-maps required for a full chain starting at
- // width x height.
- static unsigned int GetMipMapCount(unsigned int width, unsigned int height) {
- return 1 + base::bits::Log2Floor(std::max(width, height));
- }
-
- // Gets the smallest power-of-two value that is at least as high as
- // dimension. This is the POT dimension used in ScaleUpToPOT.
- static unsigned int GetPOTSize(unsigned int dimension) {
- return 1 << base::bits::Log2Ceiling(dimension);
- }
-
- // Gets the size of the buffer containing a mip-map chain, given its base
- // width, height, format and number of mip-map levels.
- static unsigned int GetMipChainSize(unsigned int base_width,
- unsigned int base_height,
- Texture::Format format,
- unsigned int num_mipmaps);
-
- // Generates mip-map levels for a single image, using the data from the base
- // level.
- // NOTE: this doesn't work for DXTC, or floating-point images.
- //
- // Parameters:
- // base_width: the width of the base image.
- // base_height: the height of the base image.
- // format: the format of the data.
- // num_mipmaps: the number of mipmaps to generate.
- // data: the data containing the base image, and enough space for the
- // mip-maps.
- static bool GenerateMipmaps(unsigned int base_width,
- unsigned int base_height,
- Texture::Format format,
- unsigned int num_mipmaps,
- unsigned char *data);
-
- // Scales an image up to power-of-two textures, using point filtering.
- // NOTE: this doesn't work for DXTC, or floating-point images.
- //
- // Parameters:
- // width: the non-power-of-two width of the original image.
- // height: the non-power-of-two height of the original image.
- // format: the format of the data.
- // src: the data containing the source data of the original image.
- // dst: a buffer with enough space for the power-of-two version. Pixels are
- // written from the end to the beginning so dst can be the same buffer as
- // src.
- static bool ScaleUpToPOT(unsigned int width,
- unsigned int height,
- Texture::Format format,
- const unsigned char *src,
- unsigned char *dst);
-
- // Scales an image to an arbitrary size, using point filtering.
- // NOTE: this doesn't work for DXTC, or floating-point images.
- //
- // Parameters:
- // src_width: the width of the original image.
- // src_height: the height of the original image.
- // format: the format of the data.
- // src: the data containing the source data of the original image.
- // dst_width: the width of the target image.
- // dst_height: the height of the target image.
- // dst: a buffer with enough space for the target version. Pixels are
- // written from the end to the beginning so dst can be the same buffer as
- // src if the transformation is an upscaling.
- static bool Scale(unsigned int src_width,
- unsigned int src_height,
- Texture::Format format,
- const unsigned char *src,
- unsigned int dst_width,
- unsigned int dst_height,
- unsigned char *dst);
-
- // adjust start points and boundaries when using DrawImage data
- // in bitmap and textures.
- // Parameters:
- // src_x: x-coordinate of the starting pixel in the source image.
- // src_y: y-coordinate of the starting pixel in the source image.
- // src_width: width of the source image to draw.
- // src_height: height of the source image to draw.
- // src_bmp_width: original width of source bitmap.
- // src_bmp_height: original height of source bitmap.
- // dest_x: x-coordinate of the starting pixel in the dest image.
- // dest_y: y-coordinate of the starting pixel in the dest image.
- // dest_width: width of the dest image to draw.
- // dest_height: height of the dest image to draw.
- // dest_bmp_width: original width of dest bitmap.
- // dest_bmp_height: original height of dest bitmap.
- // Returns:
- // false if src or dest rectangle is out of boundaries.
- static bool AdjustDrawImageBoundary(int* src_x, int* src_y,
- int* src_width, int* src_height,
- int src_bmp_width, int src_bmp_height,
- int* dest_x, int* dest_y,
- int* dest_width, int* dest_height,
- int dest_bmp_width, int dest_bmp_height);
-
- private:
- friend class IClassManager;
- static ObjectBase::Ref Create(ServiceLocator* service_locator);
-
- // pointer to the raw bitmap data
- scoped_array<uint8> image_data_;
- // format of the texture this is meant to represent.
- Texture::Format format_;
- // width of the bitmap in pixels.
- int width_;
- // height of the bitmap in pixels.
- int height_;
- // number of mipmap levels in this texture.
- unsigned int num_mipmaps_;
- // is this cube-map data
- bool is_cubemap_;
-
- // utility function used in AdjustDrawImageBoundary.
- // It adjusts start point and related measures
- // for a specific dimension.
- // Parameter:
- // src_a: the coordinate which is negative.
- // dest_a: same coordinate in the other image.
- // src_length: length measure of source image to draw.
- // dest_length: length measure of dest image to draw.
- // src_bmp_length: length measure of src image.
- // Returns:
- // true if adjust is successful.
- static bool AdjustDrawImageBoundHelper(int* src_a, int* dest_a,
- int* src_length, int* dest_length,
- int src_bmp_length);
-
- O3D_DECL_CLASS(Bitmap, ParamObject);
- DISALLOW_COPY_AND_ASSIGN(Bitmap);
-};
-
-} // namespace o3d
-
-#endif // O3D_CORE_CROSS_BITMAP_H_
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+// This file contains the declaration of Bitmap helper class that can load
+// raw 24- and 32-bit bitmaps from popular image formats. The Bitmap class
+// also interprets the file format to record the correct OpenGL buffer format.
+//
+// Trying to keep this class independent from the OpenGL API in case they
+// need retargeting later on.
+
+#ifndef O3D_CORE_CROSS_BITMAP_H_
+#define O3D_CORE_CROSS_BITMAP_H_
+
+#include <stdlib.h>
+
+#include "base/cross/bits.h"
+#include "core/cross/types.h"
+#include "core/cross/texture.h"
+
+class FilePath;
+
+namespace o3d {
+
+class MemoryReadStream;
+class RawData;
+class Pack;
+
+// Bitmap provides an API for basic image operations on bitmap images,
+// including scale and crop. The contents of bitmap can be created from
+// a RawData object via LoadFromRawData(), and also can be transfered
+// to mip of a Texure2D or a specific face of TextureCUBE via methods
+// in Texture.
+
+class Bitmap : public ParamObject {
+ public:
+ typedef SmartPointer<Bitmap> Ref;
+
+ explicit Bitmap(ServiceLocator* service_locator);
+ virtual ~Bitmap() {}
+
+ // We will fail to load images that are bigger than 4kx4k to avoid security
+ // risks. GPUs don't usually support bigger sizes anyway.
+ // The biggest bitmap buffer size with these dimensions is:
+ // 4k x 4k x 4xsizeof(float) x6 x4/3 (x6 for cube maps, x4/3 for mipmaps)
+ // That makes 2GB, representable in an unsigned int, so we will avoid wraps.
+ static const unsigned int kMaxImageDimension = 4096;
+ enum ImageFileType {
+ UNKNOWN,
+ TGA,
+ JPEG,
+ PNG,
+ DDS,
+ };
+
+ static bool CheckImageDimensions(unsigned int width, unsigned int height) {
+ return width > 0 && height > 0 &&
+ width <= kMaxImageDimension && height < kMaxImageDimension;
+ }
+
+ // Creates a copy of a bitmap, copying the pixels as well.
+ // Parameters:
+ // source: the source bitmap.
+ void CopyDeepFrom(const Bitmap &source) {
+ Allocate(source.format_, source.width_, source.height_,
+ source.num_mipmaps_, source.is_cubemap_);
+ memcpy(image_data(), source.image_data(), GetTotalSize());
+ }
+
+ // Sets the bitmap parameters from another bitmap, stealing the pixel buffer
+ // from the source bitmap.
+ // Parameters:
+ // source: the source bitmap.
+ void SetFrom(Bitmap *source) {
+ image_data_.reset();
+ format_ = source->format_;
+ width_ = source->width_;
+ height_ = source->height_;
+ num_mipmaps_ = source->num_mipmaps_;
+ is_cubemap_ = source->is_cubemap_;
+ image_data_.swap(source->image_data_);
+ }
+
+ // Allocates an uninitialized bitmap with specified parameters.
+ // Parameters:
+ // format: the format of the pixels.
+ // width: the width of the base image.
+ // height: the height of the base image.
+ // num_mipmaps: the number of mip-maps.
+ // cube_map: true if creating a cube map.
+ void Allocate(Texture::Format format,
+ unsigned int width,
+ unsigned int height,
+ unsigned int num_mipmaps,
+ bool cube_map);
+
+ // Allocates a bitmap with initialized parameters.
+ // data is zero-initialized
+ void AllocateData() {
+ image_data_.reset(new unsigned char[GetTotalSize()]);
+ memset(image_data_.get(), 0, GetTotalSize());
+ }
+
+ // Frees the data owned by the bitmap.
+ void FreeData() {
+ image_data_.reset(NULL);
+ }
+
+ // Gets the total size of the bitmap data, counting all faces and mip levels.
+ unsigned int GetTotalSize() {
+ return (is_cubemap_ ? 6 : 1) *
+ GetMipChainSize(width_, height_, format_, num_mipmaps_);
+ }
+
+ // Computes the number of bytes of a texture pixel buffer.
+ static unsigned int GetBufferSize(unsigned int width,
+ unsigned int height,
+ Texture::Format format);
+
+ // Gets the image data for a given mip-map level and cube map face.
+ // Parameters:
+ // level: mip level to get.
+ // face: face of cube to get. This parameter is ignored if
+ // this bitmap is not a cube map.
+ unsigned char *GetMipData(unsigned int level,
+ TextureCUBE::CubeFace face) const;
+
+ unsigned char *image_data() const { return image_data_.get(); }
+ Texture::Format format() const { return format_; }
+ unsigned int width() const { return width_; }
+ unsigned int height() const { return height_; }
+ unsigned int num_mipmaps() const { return num_mipmaps_; }
+ bool is_cubemap() const { return is_cubemap_; }
+
+ // Returns whether or not the dimensions of the bitmap are power-of-two.
+ bool IsPOT() const {
+ return ((width_ & (width_ - 1)) == 0) && ((height_ & (height_ - 1)) == 0);
+ }
+
+ void set_format(Texture::Format format) { format_ = format; }
+ void set_width(unsigned int n) { width_ = n; }
+ void set_height(unsigned int n) { height_ = n; }
+ void set_num_mipmaps(unsigned int n) { num_mipmaps_ = n; }
+ void set_is_cubemap(bool is_cubemap) { is_cubemap_ = is_cubemap; }
+
+ // Loads a bitmap from a file.
+ // Parameters:
+ // filename: the name of the file to load.
+ // file_type: the type of file to load. If UNKNOWN, the file type will be
+ // determined from the filename extension, and if it is not a
+ // known extension, all the loaders will be tried.
+ // generate_mipmaps: whether or not to generate all the mip-map levels.
+ bool LoadFromFile(const FilePath &filepath,
+ ImageFileType file_type,
+ bool generate_mipmaps);
+
+ // Loads a bitmap from a RawData object.
+ // Parameters:
+ // raw_data: contains the bitmap data in one of the known formats
+ // file_type: the format of the bitmap data. If UNKNOWN, the file type
+ // will be determined from the extension from raw_data's uri
+ // and if it is not a known extension, all the loaders will
+ // be tried.
+ // generate_mipmaps: whether or not to generate all the mip-map levels.
+ bool LoadFromRawData(RawData *raw_data,
+ ImageFileType file_type,
+ bool generate_mipmaps);
+
+ // Loads a bitmap from a MemoryReadStream.
+ // Parameters:
+ // stream: a stream for the bitmap data in one of the known formats
+ // filename: a filename (or uri) of the original bitmap data
+ // (may be an empty string)
+ // file_type: the format of the bitmap data. If UNKNOWN, the file type
+ // will be determined from the extension of |filename|
+ // and if it is not a known extension, all the loaders
+ // will be tried.
+ // generate_mipmaps: whether or not to generate all the mip-map levels.
+ bool LoadFromStream(MemoryReadStream *stream,
+ const String &filename,
+ ImageFileType file_type,
+ bool generate_mipmaps);
+
+ bool LoadFromPNGStream(MemoryReadStream *stream,
+ const String &filename,
+ bool generate_mipmaps);
+
+ bool LoadFromTGAStream(MemoryReadStream *stream,
+ const String &filename,
+ bool generate_mipmaps);
+
+ bool LoadFromDDSStream(MemoryReadStream *stream,
+ const String &filename,
+ bool generate_mipmaps);
+
+ bool LoadFromJPEGStream(MemoryReadStream *stream,
+ const String &filename,
+ bool generate_mipmaps);
+
+ // Saves to a PNG file. The image must be of the ARGB8 format, be a 2D image
+ // with no mip-maps (only the base level).
+ // Parameters:
+ // filename: the name of the file to into.
+ // Returns:
+ // true if successful.
+ bool SaveToPNGFile(const char* filename);
+
+ // Checks that the alpha channel for the entire bitmap is 1.0
+ bool CheckAlphaIsOne() const;
+
+ // Copy pixels from source bitmap. Scales if the width and height of source
+ // and dest do not match.
+ // Parameters:
+ // source_img: source bitmap which would be drawn.
+ // source_x: x-coordinate of the starting pixel in the source image.
+ // source_x: y-coordinate of the starting pixel in the source image.
+ // source_width: width of the source image to draw.
+ // source_height: Height of the source image to draw.
+ // dest_x: x-coordinate of the starting pixel in the dest image.
+ // dest_y: y-coordinate of the starting pixel in the dest image.
+ // dest_width: width of the dest image to draw.
+ // dest_height: height of the dest image to draw.
+ void DrawImage(Bitmap* source_img, int source_x, int source_y,
+ int source_width, int source_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height);
+
+ // Crop part of an image from src, scale it to an arbitrary size
+ // and paste in dest image. Utility function for all DrawImage
+ // function in bitmap and textures. Scale operation is based on
+ // Lanczos resampling.
+ // Note: this doesn't work for DXTC, or floating-point images.
+ //
+ // Parameters:
+ // src: source image which would be copied from.
+ // src_x: x-coordinate of the starting pixel in the src image.
+ // src_y: y-coordinate of the starting pixel in the src image.
+ // src_width: width of the part in src image to be croped.
+ // src_height: height of the part in src image to be croped.
+ // src_img_width: width of the src image.
+ // src_img_height: height of the src image.
+ // dest: dest image which would be copied to.
+ // dest_x: x-coordinate of the starting pixel in the dest image.
+ // dest_y: y-coordinate of the starting pixel in the dest image.
+ // dest_width: width of the part in dest image to be pasted to.
+ // dest_height: height of the part in dest image to be pasted to.
+ // dest_img_width: width of the dest image.
+ // dest_img_height: height of the src image.
+ // component: size of each pixel in terms of array element.
+ // Returns:
+ // true if crop and scale succeeds.
+ static void LanczosScale(const uint8* src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int src_img_width, int src_img_height,
+ uint8* dest,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int dest_img_width, int dest_img_height,
+ int component);
+
+ // Detects the type of image file based on the filename.
+ static ImageFileType GetFileTypeFromFilename(const char *filename);
+ // Detects the type of image file based on the mime-type.
+ static ImageFileType GetFileTypeFromMimeType(const char *mime_type);
+
+ // Adds filler alpha byte (0xff) after every pixel. Assumes buffer was
+ // allocated with enough storage)
+ // can convert RGB -> RGBA, BGR -> BGRA, etc.
+ static void XYZToXYZA(unsigned char *image_data, int pixel_count);
+
+ // Swaps Red and Blue components in the image.
+ static void RGBAToBGRA(unsigned char *image_data, int pixel_count);
+
+ // Gets the number of mip-maps required for a full chain starting at
+ // width x height.
+ static unsigned int GetMipMapCount(unsigned int width, unsigned int height) {
+ return 1 + base::bits::Log2Floor(std::max(width, height));
+ }
+
+ // Gets the smallest power-of-two value that is at least as high as
+ // dimension. This is the POT dimension used in ScaleUpToPOT.
+ static unsigned int GetPOTSize(unsigned int dimension) {
+ return 1 << base::bits::Log2Ceiling(dimension);
+ }
+
+ // Gets the size of the buffer containing a mip-map chain, given its base
+ // width, height, format and number of mip-map levels.
+ static unsigned int GetMipChainSize(unsigned int base_width,
+ unsigned int base_height,
+ Texture::Format format,
+ unsigned int num_mipmaps);
+
+ // Generates mip-map levels for a single image, using the data from the base
+ // level.
+ // NOTE: this doesn't work for DXTC, or floating-point images.
+ //
+ // Parameters:
+ // base_width: the width of the base image.
+ // base_height: the height of the base image.
+ // format: the format of the data.
+ // num_mipmaps: the number of mipmaps to generate.
+ // data: the data containing the base image, and enough space for the
+ // mip-maps.
+ static bool GenerateMipmaps(unsigned int base_width,
+ unsigned int base_height,
+ Texture::Format format,
+ unsigned int num_mipmaps,
+ unsigned char *data);
+
+ // Scales an image up to power-of-two textures, using point filtering.
+ // NOTE: this doesn't work for DXTC, or floating-point images.
+ //
+ // Parameters:
+ // width: the non-power-of-two width of the original image.
+ // height: the non-power-of-two height of the original image.
+ // format: the format of the data.
+ // src: the data containing the source data of the original image.
+ // dst: a buffer with enough space for the power-of-two version. Pixels are
+ // written from the end to the beginning so dst can be the same buffer as
+ // src.
+ static bool ScaleUpToPOT(unsigned int width,
+ unsigned int height,
+ Texture::Format format,
+ const unsigned char *src,
+ unsigned char *dst);
+
+ // Scales an image to an arbitrary size, using point filtering.
+ // NOTE: this doesn't work for DXTC, or floating-point images.
+ //
+ // Parameters:
+ // src_width: the width of the original image.
+ // src_height: the height of the original image.
+ // format: the format of the data.
+ // src: the data containing the source data of the original image.
+ // dst_width: the width of the target image.
+ // dst_height: the height of the target image.
+ // dst: a buffer with enough space for the target version. Pixels are
+ // written from the end to the beginning so dst can be the same buffer as
+ // src if the transformation is an upscaling.
+ static bool Scale(unsigned int src_width,
+ unsigned int src_height,
+ Texture::Format format,
+ const unsigned char *src,
+ unsigned int dst_width,
+ unsigned int dst_height,
+ unsigned char *dst);
+
+ // adjust start points and boundaries when using DrawImage data
+ // in bitmap and textures.
+ // Parameters:
+ // src_x: x-coordinate of the starting pixel in the source image.
+ // src_y: y-coordinate of the starting pixel in the source image.
+ // src_width: width of the source image to draw.
+ // src_height: height of the source image to draw.
+ // src_bmp_width: original width of source bitmap.
+ // src_bmp_height: original height of source bitmap.
+ // dest_x: x-coordinate of the starting pixel in the dest image.
+ // dest_y: y-coordinate of the starting pixel in the dest image.
+ // dest_width: width of the dest image to draw.
+ // dest_height: height of the dest image to draw.
+ // dest_bmp_width: original width of dest bitmap.
+ // dest_bmp_height: original height of dest bitmap.
+ // Returns:
+ // false if src or dest rectangle is out of boundaries.
+ static bool AdjustDrawImageBoundary(int* src_x, int* src_y,
+ int* src_width, int* src_height,
+ int src_bmp_width, int src_bmp_height,
+ int* dest_x, int* dest_y,
+ int* dest_width, int* dest_height,
+ int dest_bmp_width, int dest_bmp_height);
+
+ private:
+ friend class IClassManager;
+ static ObjectBase::Ref Create(ServiceLocator* service_locator);
+
+ // pointer to the raw bitmap data
+ scoped_array<uint8> image_data_;
+ // format of the texture this is meant to represent.
+ Texture::Format format_;
+ // width of the bitmap in pixels.
+ int width_;
+ // height of the bitmap in pixels.
+ int height_;
+ // number of mipmap levels in this texture.
+ unsigned int num_mipmaps_;
+ // is this cube-map data
+ bool is_cubemap_;
+
+ // utility function used in AdjustDrawImageBoundary.
+ // It adjusts start point and related measures
+ // for a specific dimension.
+ // Parameter:
+ // src_a: the coordinate which is negative.
+ // dest_a: same coordinate in the other image.
+ // src_length: length measure of source image to draw.
+ // dest_length: length measure of dest image to draw.
+ // src_bmp_length: length measure of src image.
+ // Returns:
+ // true if adjust is successful.
+ static bool AdjustDrawImageBoundHelper(int* src_a, int* dest_a,
+ int* src_length, int* dest_length,
+ int src_bmp_length);
+
+ // utility function for LanczosScale function.
+ // Given an image, It can scale the image in one dimension to the new
+ // length using a Lanczos3 windowsed-sinc filter. This filter has
+ // fairly large support, in choosing it we favor quality over speed.
+ // In parameters we assume the current dimension we are scaling is
+ // width, but by changing the parameter, we can easily using this
+ // function on height as well.
+ // Parameter:
+ // src: source image which would be copied from.
+ // src_x: x-coordinate of the starting pixel in the source image.
+ // src_y: y-coordinate of the starting pixel in the source image.
+ // width: width of the part in src image to be croped.
+ // height: height of the part in src image to be croped.
+ // src_bmp_width: original width of source bitmap.
+ // src_bmp_height: original height of source bitmap.
+ // dest: dest image which would be copied to.
+ // dest_x: x-coordinate of the starting pixel in the dest image.
+ // dest_y: y-coordinate of the starting pixel in the dest image.
+ // dest_bmp_width: original width of dest bitmap.
+ // dest_bmp_height: original height of dest bitmap.
+ // isWidth: which dimension we are working on.
+ // components: size of each pixel in terms of array element.
+ static void LanczosResize1D(const uint8* src, int src_x, int src_y,
+ int width, int height,
+ int src_bmp_width, int src_bmp_height,
+ uint8* dest, int dest_x, int dest_y,
+ int nwidth,
+ int dest_bmp_width, int dest_bmp_height,
+ bool isWidth, int components);
+
+ O3D_DECL_CLASS(Bitmap, ParamObject);
+ DISALLOW_COPY_AND_ASSIGN(Bitmap);
+};
+
+} // namespace o3d
+
+#endif // O3D_CORE_CROSS_BITMAP_H_
diff --git a/o3d/core/cross/bitmap_test.cc b/o3d/core/cross/bitmap_test.cc
index 1d832ef..230a589 100644
--- a/o3d/core/cross/bitmap_test.cc
+++ b/o3d/core/cross/bitmap_test.cc
@@ -1036,62 +1036,62 @@ static unsigned char kpng_8x4_drawImage_left[128] = {
static unsigned char kpng_8x4_drawImage_scale_up[128] = {
// expected result of scale up from 2x2 to 8x4.
- 0x3f, 0x3f, 0x3f, 0xff, 0x48, 0x48, 0x48, 0xff,
- 0x51, 0x51, 0x51, 0xff, 0x5a, 0x5a, 0x5a, 0xff,
- 0x64, 0x64, 0x64, 0xff, 0x6d, 0x6d, 0x6d, 0xff,
- 0x76, 0x76, 0x76, 0xff, 0x7f, 0x7f, 0x7f, 0xff,
- 0x2a, 0x2a, 0x2a, 0xff, 0x32, 0x32, 0x32, 0xff,
- 0x39, 0x39, 0x39, 0xff, 0x41, 0x41, 0x41, 0xff,
- 0x48, 0x48, 0x48, 0xff, 0x50, 0x50, 0x50, 0xff,
- 0x57, 0x57, 0x57, 0xff, 0x5f, 0x5f, 0x5f, 0xff,
- 0x15, 0x15, 0x15, 0xff, 0x1b, 0x1b, 0x1b, 0xff,
- 0x21, 0x21, 0x21, 0xff, 0x27, 0x27, 0x27, 0xff,
- 0x2d, 0x2d, 0x2d, 0xff, 0x33, 0x33, 0x33, 0xff,
- 0x39, 0x39, 0x39, 0xff, 0x3f, 0x3f, 0x3f, 0xff,
- 0x00, 0x00, 0x00, 0xff, 0x04, 0x04, 0x04, 0xff,
- 0x09, 0x09, 0x09, 0xff, 0x0d, 0x0d, 0x0d, 0xff,
- 0x12, 0x12, 0x12, 0xff, 0x16, 0x16, 0x16, 0xff,
- 0x1b, 0x1b, 0x1b, 0xff, 0x1f, 0x1f, 0x1f, 0xff,
+ 0x38, 0x38, 0x38, 0xff, 0x43, 0x43, 0x43, 0xff,
+ 0x52, 0x52, 0x52, 0xff, 0x63, 0x63, 0x63, 0xff,
+ 0x77, 0x77, 0x77, 0xff, 0x88, 0x88, 0x88, 0xff,
+ 0x96, 0x96, 0x96, 0xff, 0x90, 0x90, 0x90, 0xff,
+ 0x25, 0x25, 0x25, 0xff, 0x2c, 0x2c, 0x2c, 0xff,
+ 0x36, 0x36, 0x36, 0xff, 0x45, 0x45, 0x45, 0xff,
+ 0x54, 0x54, 0x54, 0xff, 0x63, 0x63, 0x63, 0xff,
+ 0x6e, 0x6e, 0x6e, 0xff, 0x69, 0x69, 0x69, 0xff,
+ 0x0b, 0x0b, 0x0b, 0xff, 0x0d, 0x0d, 0x0d, 0xff,
+ 0x13, 0x13, 0x13, 0xff, 0x1c, 0x1c, 0x1c, 0xff,
+ 0x28, 0x28, 0x28, 0xff, 0x31, 0x31, 0x31, 0xff,
+ 0x39, 0x39, 0x39, 0xff, 0x35, 0x35, 0x35, 0xff,
+ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
+ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
+ 0x05, 0x05, 0x05, 0xff, 0x0c, 0x0c, 0x0c, 0xff,
+ 0x11, 0x11, 0x11, 0xff, 0x0e, 0x0e, 0x0e, 0xff,
};
static unsigned char kpng_8x4_drawImage_scale_down[128] = {
// expected result of scale down from 8x8 to 4x4.
- 0xa8, 0xa8, 0xa8, 0xff, 0xaf, 0xaf, 0xaf, 0xff,
- 0xb6, 0xb6, 0xb6, 0xff, 0xbd, 0xbd, 0xbd, 0xff,
+ 0xa0, 0xa0, 0xa0, 0xff, 0xa7, 0xa7, 0xa7, 0xff,
+ 0xad, 0xad, 0xad, 0xff, 0xb3, 0xb3, 0xb3, 0xff,
0x38, 0x70, 0xe0, 0xff, 0x3a, 0x74, 0xe8, 0xff,
0x3c, 0x78, 0xf0, 0xff, 0x3e, 0x7c, 0xf8, 0xff,
- 0x70, 0x70, 0x70, 0xff, 0x77, 0x77, 0x77, 0xff,
- 0x7e, 0x7e, 0x7e, 0xff, 0x85, 0x85, 0x85, 0xff,
+ 0x6d, 0x6d, 0x6d, 0xff, 0x74, 0x74, 0x74, 0xff,
+ 0x7a, 0x7a, 0x7a, 0xff, 0x80, 0x80, 0x80, 0xff,
0x28, 0x50, 0xa0, 0xff, 0x2a, 0x54, 0xa8, 0xff,
0x2c, 0x58, 0xb0, 0xff, 0x2e, 0x5c, 0xb8, 0xff,
- 0x38, 0x38, 0x38, 0xff, 0x3f, 0x3f, 0x3f, 0xff,
- 0x46, 0x46, 0x46, 0xff, 0x4d, 0x4d, 0x4d, 0xff,
+ 0x3d, 0x3d, 0x3d, 0xff, 0x44, 0x44, 0x44, 0xff,
+ 0x4a, 0x4a, 0x4a, 0xff, 0x50, 0x50, 0x50, 0xff,
0x18, 0x30, 0x60, 0xff, 0x1a, 0x34, 0x68, 0xff,
0x1c, 0x38, 0x70, 0xff, 0x1e, 0x3c, 0x78, 0xff,
- 0x00, 0x00, 0x00, 0xff, 0x07, 0x07, 0x07, 0xff,
- 0x0e, 0x0e, 0x0e, 0xff, 0x15, 0x15, 0x15, 0xff,
+ 0x0a, 0x0a, 0x0a, 0xff, 0x11, 0x11, 0x11, 0xff,
+ 0x17, 0x17, 0x17, 0xff, 0x1d, 0x1d, 0x1d, 0xff,
0x08, 0x10, 0x20, 0xff, 0x0a, 0x14, 0x28, 0xff,
0x0c, 0x18, 0x30, 0xff, 0x0e, 0x1c, 0x38, 0xff,
};
static unsigned char kpng_8x4_drawImage_scale_out[128] = {
// expected result of scale src image larger than dest image.
- 0x63, 0x63, 0x63, 0xff, 0x65, 0x65, 0x65, 0xff,
- 0x67, 0x67, 0x67, 0xff, 0x69, 0x69, 0x69, 0xff,
- 0x6c, 0x6c, 0x6c, 0xff, 0x6e, 0x6e, 0x6e, 0xff,
- 0x70, 0x70, 0x70, 0xff, 0x72, 0x72, 0x72, 0xff,
- 0x53, 0x53, 0x53, 0xff, 0x55, 0x55, 0x55, 0xff,
- 0x57, 0x57, 0x57, 0xff, 0x59, 0x59, 0x59, 0xff,
+ 0x64, 0x64, 0x64, 0xff, 0x66, 0x66, 0x66, 0xff,
+ 0x68, 0x68, 0x68, 0xff, 0x6a, 0x6a, 0x6a, 0xff,
+ 0x6d, 0x6d, 0x6d, 0xff, 0x6f, 0x6f, 0x6f, 0xff,
+ 0x71, 0x71, 0x71, 0xff, 0x73, 0x73, 0x73, 0xff,
+ 0x58, 0x58, 0x58, 0xff, 0x5a, 0x5a, 0x5a, 0xff,
0x5c, 0x5c, 0x5c, 0xff, 0x5e, 0x5e, 0x5e, 0xff,
- 0x60, 0x60, 0x60, 0xff, 0x62, 0x62, 0x62, 0xff,
- 0x43, 0x43, 0x43, 0xff, 0x45, 0x45, 0x45, 0xff,
+ 0x61, 0x61, 0x61, 0xff, 0x63, 0x63, 0x63, 0xff,
+ 0x65, 0x65, 0x65, 0xff, 0x67, 0x67, 0x67, 0xff,
+ 0x3e, 0x3e, 0x3e, 0xff, 0x40, 0x40, 0x40, 0xff,
+ 0x42, 0x42, 0x42, 0xff, 0x44, 0x44, 0x44, 0xff,
0x47, 0x47, 0x47, 0xff, 0x49, 0x49, 0x49, 0xff,
- 0x4c, 0x4c, 0x4c, 0xff, 0x4e, 0x4e, 0x4e, 0xff,
- 0x50, 0x50, 0x50, 0xff, 0x52, 0x52, 0x52, 0xff,
- 0x33, 0x33, 0x33, 0xff, 0x35, 0x35, 0x35, 0xff,
- 0x37, 0x37, 0x37, 0xff, 0x39, 0x39, 0x39, 0xff,
- 0x3c, 0x3c, 0x3c, 0xff, 0x3e, 0x3e, 0x3e, 0xff,
- 0x40, 0x40, 0x40, 0xff, 0x42, 0x42, 0x42, 0xff,
+ 0x4b, 0x4b, 0x4b, 0xff, 0x4d, 0x4d, 0x4d, 0xff,
+ 0x32, 0x32, 0x32, 0xff, 0x34, 0x34, 0x34, 0xff,
+ 0x36, 0x36, 0x36, 0xff, 0x38, 0x38, 0x38, 0xff,
+ 0x3b, 0x3b, 0x3b, 0xff, 0x3d, 0x3d, 0x3d, 0xff,
+ 0x3f, 0x3f, 0x3f, 0xff, 0x41, 0x41, 0x41, 0xff,
};
static unsigned char kpng_8x4_drawImage_flip[128] = {
diff --git a/o3d/core/cross/texture.cc b/o3d/core/cross/texture.cc
index 0cc784f..008e2ef 100644
--- a/o3d/core/cross/texture.cc
+++ b/o3d/core/cross/texture.cc
@@ -123,7 +123,7 @@ void Texture2D::DrawImage(Bitmap* src_img,
// the entire bitmap on dest image, just perform memcpy.
if (src_x == 0 && src_y == 0 && dst_x == 0 && dst_y == 0 &&
src_img->width() == mip_width && src_img->height() == mip_height &&
- static_cast<unsigned int>(src_width) == src_img->width() &&
+ static_cast<unsigned int>(src_width) == src_img->width() &&
static_cast<unsigned int>(src_height) == src_img->height() &&
static_cast<unsigned int>(dst_width) == mip_width &&
static_cast<unsigned int>(dst_height) == mip_height) {
@@ -157,12 +157,12 @@ void Texture2D::DrawImage(Bitmap* src_img,
uint8* src_img_data = src_img->image_data();
uint8* mip_data = static_cast<uint8*>(data);
- Bitmap::BilinearInterpolateScale(src_img_data, src_x, src_y,
- src_width, src_height,
- src_img->width(), src_img->height(),
- mip_data, dst_x, dst_y,
- dst_width, dst_height,
- mip_width, mip_height, components);
+ Bitmap::LanczosScale(src_img_data, src_x, src_y,
+ src_width, src_height,
+ src_img->width(), src_img->height(),
+ mip_data, dst_x, dst_y,
+ dst_width, dst_height,
+ mip_width, mip_height, components);
this->Unlock(dest_mip);
}
@@ -312,12 +312,12 @@ void TextureCUBE::DrawImage(Bitmap* src_img,
uint8* src_img_data = src_img->image_data();
uint8* mip_data = static_cast<uint8*>(data);
- Bitmap::BilinearInterpolateScale(src_img_data, src_x, src_y,
- src_width, src_height,
- src_img->width(), src_img->height(),
- mip_data, dst_x, dst_y,
- dst_width, dst_height,
- mip_length, mip_length, components);
+ Bitmap::LanczosScale(src_img_data, src_x, src_y,
+ src_width, src_height,
+ src_img->width(), src_img->height(),
+ mip_data, dst_x, dst_y,
+ dst_width, dst_height,
+ mip_length, mip_length, components);
this->Unlock(dest_face, dest_mip);
}