Improve flip_image avoiding a temporary image to get pixels.

This commit is contained in:
David Capello 2012-02-19 22:32:44 -03:00
parent 73fc81ec58
commit ed268767d9
2 changed files with 42 additions and 26 deletions

View File

@ -20,25 +20,46 @@
#include "raster/algorithm/flip_image.h"
#include "base/unique_ptr.h"
#include "gfx/rect.h"
#include "raster/image.h"
#include <vector>
namespace raster { namespace algorithm {
void flip_image(Image* image, const gfx::Rect& bounds, FlipType flipType)
{
UniquePtr<Image> area(image_crop(image, bounds.x, bounds.y, bounds.w, bounds.h, 0));
int x2 = bounds.x+bounds.w-1;
int y2 = bounds.y+bounds.h-1;
int x, y;
switch (flipType) {
for (y=0; y<bounds.h; ++y)
for (x=0; x<bounds.w; ++x)
image_putpixel(image,
(flipType == FlipHorizontal ? x2-x: bounds.x+x),
(flipType == FlipVertical ? y2-y: bounds.y+y),
image_getpixel(area, x, y));
case FlipHorizontal:
for (int y=bounds.y; y<bounds.y+bounds.h; ++y) {
int u = bounds.x+bounds.w-1;
for (int x=bounds.x; x<bounds.x+bounds.w/2; ++x, --u) {
uint32_t c1 = image_getpixel(image, x, y);
uint32_t c2 = image_getpixel(image, u, y);
image_putpixel(image, x, y, c2);
image_putpixel(image, u, y, c1);
}
}
break;
case FlipVertical: {
int section_size = image_line_size(image, bounds.w);
std::vector<uint8_t> tmpline(section_size);
int v = bounds.y+bounds.h-1;
for (int y=bounds.y; y<bounds.y+bounds.h/2; ++y, --v) {
uint8_t* address1 = static_cast<uint8_t*>(image_address(image, bounds.x, y));
uint8_t* address2 = static_cast<uint8_t*>(image_address(image, bounds.x, v));
// Swap lines.
std::copy(address1, address1+section_size, tmpline.begin());
std::copy(address2, address2+section_size, address1);
std::copy(tmpline.begin(), tmpline.end(), address2);
}
break;
}
}
}
} }

View File

@ -100,25 +100,22 @@ void image_resize(const Image* src, Image* dst, ResizeMethod method, const Palet
int image_count_diff(const Image* i1, const Image* i2);
bool image_shrink_rect(Image *image, int *x1, int *y1, int *x2, int *y2, int refpixel);
inline int pixelformat_shift(PixelFormat pixelFormat)
{
return ((pixelFormat == IMAGE_RGB)? 2:
(pixelFormat == IMAGE_GRAYSCALE)? 1: 0);
}
#include "raster/image_traits.h"
inline int pixelformat_line_size(PixelFormat format, int width)
inline int pixelformat_line_size(PixelFormat pixelFormat, int width)
{
return (width << pixelformat_shift(format));
}
inline int image_shift(const Image* image)
{
return pixelformat_shift(image->getPixelFormat());
switch (pixelFormat) {
case IMAGE_RGB: return RgbTraits::scanline_size(width);
case IMAGE_GRAYSCALE: return GrayscaleTraits::scanline_size(width);
case IMAGE_INDEXED: return IndexedTraits::scanline_size(width);
case IMAGE_BITMAP: return BitmapTraits::scanline_size(width);
}
return 0;
}
inline int image_line_size(const Image* image, int width)
{
return (width << image_shift(image));
return pixelformat_line_size(image->getPixelFormat(), width);
}
inline void* image_address(Image* image, int x, int y)
@ -126,6 +123,4 @@ inline void* image_address(Image* image, int x, int y)
return ((void *)(image->line[y] + image_line_size(image, x)));
}
#include "raster/image_traits.h"
#endif