diff --git a/ChangeLog b/ChangeLog index 3f6814e94..4f8ac99fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-08-02 David A. Capello + + * src/util/render.cpp (merge_zoomed_image): unified all + merge_zoomed_image8/16/32 in one generic method (and fixed + critical bugs). + 2009-06-14 David A. Capello * src/commands/cmd_rotate_canvas.cpp: Added. diff --git a/makefile.lst b/makefile.lst index 6ce38be71..45488c509 100644 --- a/makefile.lst +++ b/makefile.lst @@ -181,6 +181,7 @@ COMMON_SOURCES = \ src/raster/dirty.cpp \ src/raster/gfxobj.cpp \ src/raster/image.cpp \ + src/raster/image_impl.cpp \ src/raster/layer.cpp \ src/raster/mask.cpp \ src/raster/palette.cpp \ diff --git a/src/raster/image_impl.cpp b/src/raster/image_impl.cpp new file mode 100644 index 000000000..62749a139 --- /dev/null +++ b/src/raster/image_impl.cpp @@ -0,0 +1,539 @@ +/* ASE - Allegro Sprite Editor + * Copyright (C) 2001-2009 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include "raster/image_impl.h" + +template<> +void ImageImpl::to_allegro(BITMAP *bmp, int _x, int _y) const +{ + const_address_t addr = raw_pixels(); + unsigned long bmp_address; + int depth = bitmap_color_depth(bmp); + int x, y; + + bmp_select(bmp); + + switch (depth) { + + case 8: +#if defined GFX_MODEX && !defined ALLEGRO_UNIX + if (is_planar_bitmap(bmp)) { + for (y=0; yline[_y]; + + for (x=0; xw; x++) { + outportw(0x3C4, (0x100<<((_x+x)&3))|2); + bmp_write8(bmp_address+((_x+x)>>2), + makecol8((*addr) & 0xff, + ((*addr)>>8) & 0xff, + ((*addr)>>16) & 0xff)); + addr++; + } + + _y++; + } + } + else { +#endif + for (y=0; y>8) & 0xff, + ((*addr)>>16) & 0xff)); + addr++; + bmp_address++; + } + + _y++; + } +#if defined GFX_MODEX && !defined ALLEGRO_UNIX + } +#endif + break; + + case 15: + _x <<= 1; + + for (y=0; y>8) & 0xff, + ((*addr)>>16) & 0xff)); + addr++; + bmp_address += 2; + } + + _y++; + } + break; + + case 16: + _x <<= 1; + + for (y=0; y>8) & 0xff, + ((*addr)>>16) & 0xff)); + addr++; + bmp_address += 2; + } + + _y++; + } + break; + + case 24: + _x *= 3; + + for (y=0; y>8) & 0xff, + ((*addr)>>16) & 0xff)); + addr++; + bmp_address += 3; + } + + _y++; + } + break; + + case 32: + _x <<= 2; + + for (y=0; y>8) & 0xff, + ((*addr)>>16) & 0xff, + ((*addr)>>24) & 0xff)); + addr++; + bmp_address += 4; + } + + _y++; + } + break; + } + + bmp_unwrite_line(bmp); +} + +template<> +void ImageImpl::to_allegro(BITMAP *bmp, int _x, int _y) const +{ + const_address_t addr = raw_pixels(); + unsigned long bmp_address; + int depth = bitmap_color_depth(bmp); + int x, y; + + bmp_select(bmp); + + switch (depth) { + + case 8: +#if defined GFX_MODEX && !defined ALLEGRO_UNIX + if (is_planar_bitmap(bmp)) { + for (y=0; yline[_y]; + + for (x=0; x>2), + _index_cmap[(*addr) & 0xff]); + addr++; + } + + _y++; + } + } + else { +#endif + for (y=0; y +void ImageImpl::to_allegro(BITMAP *bmp, int _x, int _y) const +{ +#define RGB_TRIPLET \ + _rgb_scale_6[_current_palette[_index_cmap[(*addr)]].r], \ + _rgb_scale_6[_current_palette[_index_cmap[(*addr)]].g], \ + _rgb_scale_6[_current_palette[_index_cmap[(*addr)]].b] + + const_address_t addr = raw_pixels(); + unsigned long bmp_address; + int depth = bitmap_color_depth(bmp); + int x, y; + + bmp_select(bmp); + + switch (depth) { + + case 8: +#if defined GFX_MODEX && !defined ALLEGRO_UNIX + if (is_planar_bitmap (bmp)) { + for (y=0; yline[_y]; + + for (x=0; x>2), _index_cmap[(*addr)]); + address++; + } + + _y++; + } + } + else { +#endif + for (y=0; y +void ImageImpl::to_allegro(BITMAP *bmp, int _x, int _y) const +{ + const_address_t addr; + unsigned long bmp_address; + int depth = bitmap_color_depth(bmp); + div_t d, beg_d = div(0, 8); + int color[2]; + int x, y; + + bmp_select(bmp); + + switch (depth) { + + case 8: + color[0] = makecol8(0, 0, 0); + color[1] = makecol8(255, 255, 255); + +#if defined GFX_MODEX && !defined ALLEGRO_UNIX + if (is_planar_bitmap(bmp)) { + for (y=0; yline[_y]; + + d = beg_d; + for (x=0; x>2), + color[((*addr) & (1< +#include + +#include "raster/image.h" template class ImageImpl : public Image @@ -27,6 +30,8 @@ class ImageImpl : public Image typedef typename Traits::address_t address_t; typedef typename Traits::const_address_t const_address_t; +public: // raw access to pixel-data + inline address_t raw_pixels() { return (address_t)dat; } @@ -44,7 +49,7 @@ class ImageImpl : public Image assert(y >= 0 && y < h); return ((const_address_t*)line)[y]; } - + public: ImageImpl(int w, int h) @@ -485,522 +490,4 @@ void ImageImpl::merge(const Image* src, int x, int y, int opacity, } } -template<> -void ImageImpl::to_allegro(BITMAP *bmp, int _x, int _y) const -{ - const_address_t addr = raw_pixels(); - unsigned long bmp_address; - int depth = bitmap_color_depth(bmp); - int x, y; - - bmp_select(bmp); - - switch (depth) { - - case 8: -#if defined GFX_MODEX && !defined ALLEGRO_UNIX - if (is_planar_bitmap(bmp)) { - for (y=0; yline[_y]; - - for (x=0; xw; x++) { - outportw(0x3C4, (0x100<<((_x+x)&3))|2); - bmp_write8(bmp_address+((_x+x)>>2), - makecol8((*addr) & 0xff, - ((*addr)>>8) & 0xff, - ((*addr)>>16) & 0xff)); - addr++; - } - - _y++; - } - } - else { -#endif - for (y=0; y>8) & 0xff, - ((*addr)>>16) & 0xff)); - addr++; - bmp_address++; - } - - _y++; - } -#if defined GFX_MODEX && !defined ALLEGRO_UNIX - } -#endif - break; - - case 15: - _x <<= 1; - - for (y=0; y>8) & 0xff, - ((*addr)>>16) & 0xff)); - addr++; - bmp_address += 2; - } - - _y++; - } - break; - - case 16: - _x <<= 1; - - for (y=0; y>8) & 0xff, - ((*addr)>>16) & 0xff)); - addr++; - bmp_address += 2; - } - - _y++; - } - break; - - case 24: - _x *= 3; - - for (y=0; y>8) & 0xff, - ((*addr)>>16) & 0xff)); - addr++; - bmp_address += 3; - } - - _y++; - } - break; - - case 32: - _x <<= 2; - - for (y=0; y>8) & 0xff, - ((*addr)>>16) & 0xff, - ((*addr)>>24) & 0xff)); - addr++; - bmp_address += 4; - } - - _y++; - } - break; - } - - bmp_unwrite_line(bmp); -} - -template<> -void ImageImpl::to_allegro(BITMAP *bmp, int _x, int _y) const -{ - const_address_t addr = raw_pixels(); - unsigned long bmp_address; - int depth = bitmap_color_depth(bmp); - int x, y; - - bmp_select(bmp); - - switch (depth) { - - case 8: -#if defined GFX_MODEX && !defined ALLEGRO_UNIX - if (is_planar_bitmap(bmp)) { - for (y=0; yline[_y]; - - for (x=0; x>2), - _index_cmap[(*addr) & 0xff]); - addr++; - } - - _y++; - } - } - else { -#endif - for (y=0; y -void ImageImpl::to_allegro(BITMAP *bmp, int _x, int _y) const -{ -#define RGB_TRIPLET \ - _rgb_scale_6[_current_palette[_index_cmap[(*addr)]].r], \ - _rgb_scale_6[_current_palette[_index_cmap[(*addr)]].g], \ - _rgb_scale_6[_current_palette[_index_cmap[(*addr)]].b] - - const_address_t addr = raw_pixels(); - unsigned long bmp_address; - int depth = bitmap_color_depth(bmp); - int x, y; - - bmp_select(bmp); - - switch (depth) { - - case 8: -#if defined GFX_MODEX && !defined ALLEGRO_UNIX - if (is_planar_bitmap (bmp)) { - for (y=0; yline[_y]; - - for (x=0; x>2), _index_cmap[(*addr)]); - address++; - } - - _y++; - } - } - else { -#endif - for (y=0; y -void ImageImpl::to_allegro(BITMAP *bmp, int _x, int _y) const -{ - const_address_t addr; - unsigned long bmp_address; - int depth = bitmap_color_depth(bmp); - div_t d, beg_d = div(0, 8); - int color[2]; - int x, y; - - bmp_select(bmp); - - switch (depth) { - - case 8: - color[0] = makecol8(0, 0, 0); - color[1] = makecol8(255, 255, 255); - -#if defined GFX_MODEX && !defined ALLEGRO_UNIX - if (is_planar_bitmap(bmp)) { - for (y=0; yline[_y]; - - d = beg_d; - for (x=0; x>2), - color[((*addr) & (1< +class BlenderHelper +{ + BLEND_COLOR m_blend_color; +public: + BlenderHelper(int blend_mode) + { + m_blend_color = Traits::get_blender(blend_mode); + } + + inline void operator()(typename Traits::address_t& scanline_address, + typename Traits::address_t& dst_address, + typename Traits::address_t& src_address, + int& opacity) + { + *scanline_address = (*m_blend_color)(*dst_address, *src_address, opacity); + } +}; + +template<> +class BlenderHelper +{ + int m_blend_mode; +public: + BlenderHelper(int blend_mode) + { + m_blend_mode = blend_mode; + } + + inline void operator()(IndexedTraits::address_t& scanline_address, + IndexedTraits::address_t& dst_address, + IndexedTraits::address_t& src_address, + int& opacity) + { + if (m_blend_mode == BLEND_MODE_COPY) { + *scanline_address = *src_address; + } + else { + if (*src_address) { + if (color_map) + *scanline_address = color_map->data[*src_address][*dst_address]; + else + *scanline_address = *src_address; + } + else + *scanline_address = *dst_address; + } + } +}; + +template +static void merge_zoomed_image(Image *dst, Image *src, + int x, int y, int opacity, + int blend_mode, int zoom) +{ + BlenderHelper blender(blend_mode); + Traits::address_t src_address; + Traits::address_t dst_address, dst_address_end; + Traits::address_t scanline, scanline_address; + int src_x, src_y, src_w, src_h; + int dst_x, dst_y, dst_w, dst_h; + int box_x, box_y, box_w, box_h; + int offsetx, offsety; + int line_h, bottom; + + box_w = 1<w; + src_h = src->h; + + dst_x = x; + dst_y = y; + dst_w = src->w<h<>zoom; + src_w -= (-dst_x)>>zoom; + dst_w -= (-dst_x); + offsetx = box_w - ((-dst_x) % box_w); + dst_x = 0; + } + else + offsetx = 0; + + if (dst_y < 0) { + src_y += (-dst_y)>>zoom; + src_h -= (-dst_y)>>zoom; + dst_h -= (-dst_y); + offsety = box_h - ((-dst_y) % box_h); + dst_y = 0; + } + else + offsety = 0; + + if (dst_x+dst_w > dst->w) { + src_w -= (dst_x+dst_w-dst->w) >> zoom; + dst_w = dst->w - dst_x; + } + + if (dst_y+dst_h > dst->h) { + src_h -= (dst_y+dst_h-dst->h) >> zoom; + dst_h = dst->h - dst_y; + } + + if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0)) + return; + + bottom = dst_y+dst_h-1; + + // the scanline variable is used to + scanline = new Traits::pixel_t[src_w]; + + // for each line to draw of the source image... + for (y=0; y= 0 && src_x < src->w); + assert(dst_x >= 0 && dst_x < dst->w); + + // get addresses to each line (beginning of 'src', 'dst', etc.) + src_address = ((ImageImpl*)src)->line_address(src_y) + src_x; + dst_address = ((ImageImpl*)dst)->line_address(dst_y) + dst_x; + dst_address_end = dst_address + dst_w; + scanline_address = scanline; + + // read 'src' and 'dst' and blend them, put the result in `scanline' + for (x=0; x= scanline); + assert(scanline_address < scanline + src_w); + assert(src_address >= ((ImageImpl*)src)->line_address(src_y) + src_x); + assert(src_address < ((ImageImpl*)src)->line_address(src_y) + src_x + src_w); + assert(dst_address >= ((ImageImpl*)dst)->line_address(dst_y) + dst_x); + assert(dst_address < ((ImageImpl*)dst)->line_address(dst_y) + dst_x + dst_w); + assert(dst_address < dst_address_end); + + blender(scanline_address, dst_address, src_address, opacity); + + src_address++; + if (x == 0 && offsetx > 0) + dst_address += offsetx; + else + dst_address += box_w; + scanline_address++; + + if (dst_address >= dst_address_end) + break; + } + + // get the 'height' of the line to be painted in 'dst' + if ((offsety > 0) && (y == 0)) + line_h = offsety; + else + line_h = box_h; + + // draw the line in `dst' + for (box_y=0; box_y*)dst)->line_address(dst_y) + dst_x; + dst_address_end = dst_address + dst_w; + scanline_address = scanline; + + x = 0; + + // first pixel + if (offsetx > 0) { + for (box_x=0; box_x= scanline); + assert(scanline_address < scanline + src_w); + assert(dst_address >= ((ImageImpl*)dst)->line_address(dst_y) + dst_x); + assert(dst_address < ((ImageImpl*)dst)->line_address(dst_y) + dst_x + dst_w); + assert(dst_address < dst_address_end); + + (*dst_address++) = (*scanline_address); + + if (dst_address >= dst_address_end) + goto done_with_line; + } + + scanline_address++; + x++; + } + + // the rest of the line + for (; x= ((ImageImpl*)dst)->line_address(dst_y) + dst_x); + assert(dst_address < ((ImageImpl*)dst)->line_address(dst_y) + dst_x + dst_w); + + (*dst_address++) = (*scanline_address); + + if (dst_address >= dst_address_end) + goto done_with_line; + } + + scanline_address++; + } + +done_with_line:; + + if (++dst_y > bottom) + goto done_with_blit; + } + + // go to the next line in the source image + src_y++; + } + +done_with_blit:; + delete[] scanline; +} + +////////////////////////////////////////////////////////////////////// +// Render engine static int global_opacity = 255; static Layer *selected_layer = NULL; static Image *rastering_image = NULL; -static void render_layer(Sprite *sprite, Layer *layer, Image *image, +static void render_layer(Sprite* sprite, Layer* layer, Image* image, int source_x, int source_y, int frame, int zoom, - void (*zoomed_func)(Image *, Image *, int, int, int, int, int), + void (*zoomed_func)(Image*, Image*, int, int, int, int, int), bool render_background, bool render_transparent); -static void merge_zoomed_image8(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom); -static void merge_zoomed_image16(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom); -static void merge_zoomed_image32(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom); - void set_preview_image(Layer *layer, Image *image) { selected_layer = layer; @@ -76,17 +290,17 @@ Image *render_sprite(Sprite *sprite, case IMAGE_RGB: depth = 32; - zoomed_func = merge_zoomed_image32; + zoomed_func = merge_zoomed_image; break; case IMAGE_GRAYSCALE: depth = 8; - zoomed_func = merge_zoomed_image16; + zoomed_func = merge_zoomed_image; break; case IMAGE_INDEXED: depth = 8; - zoomed_func = merge_zoomed_image8; + zoomed_func = merge_zoomed_image; break; default: @@ -259,439 +473,3 @@ static void render_layer(Sprite *sprite, Layer *layer, Image *image, } } - -static void merge_zoomed_image8(Image *dst, Image *src, - int x, int y, int opacity, - int blend_mode, int zoom) -{ - ase_uint8 *src_address; - ase_uint8 *dst_address; - ase_uint8 *scanline, *scanline_address; - int src_x, src_y, src_w, src_h; - int dst_x, dst_y, dst_w, dst_h; - int box_x, box_y, box_w, box_h; - int sizeof_box, offsetx, offsety; - int line_x, line_h, right, bottom; - - box_w = 1<w; - src_h = src->h; - - dst_x = x; - dst_y = y; - dst_w = src->w<h<>zoom; - src_w -= (-dst_x)>>zoom; - dst_w -= (-dst_x); - offsetx = box_w - ((-dst_x) % box_w); - dst_x = 0; - } - else - offsetx = 0; - - if (dst_y < 0) { - src_y += (-dst_y)>>zoom; - src_h -= (-dst_y)>>zoom; - dst_h -= (-dst_y); - offsety = box_h - ((-dst_y) % box_h); - dst_y = 0; - } - else - offsety = 0; - - if (dst_x+dst_w > dst->w) { - src_w -= (dst_x+dst_w-dst->w) >> zoom; - dst_w = dst->w - dst_x; - } - - if (dst_y+dst_h > dst->h) { - src_h -= (dst_y+dst_h-dst->h) >> zoom; - dst_h = dst->h - dst_y; - } - - if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0)) - return; - - sizeof_box = sizeof(ase_uint8) * box_w; - right = dst_x+dst_w-1; - bottom = dst_y+dst_h-1; - - scanline = (ase_uint8*)jmalloc(sizeof(ase_uint8) * src_w); - - /* merge process */ - - for (y=0; yline)[src_y] + src_x; - dst_address = ((ase_uint8 **)dst->line)[dst_y] + dst_x; - scanline_address = scanline; - - /* read `src' and `dst' and blend them, put the result in `scanline' */ - for (x=0; xdata[*src_address][*dst_address]; - else - *scanline_address = *src_address; - } - else - *scanline_address = *dst_address; - } - - src_address++; - dst_address += box_w; - scanline_address++; - } - - /* get the `height' of the line */ - if ((offsety > 0) && (y == 0)) - line_h = offsety; - else - line_h = box_h; - - /* put the line in `dst' */ - for (box_y=0; box_yline)[dst_y] + dst_x; - scanline_address = scanline; - - line_x = dst_x; - x = 0; - - /* first pixel */ - if (offsetx > 0) { - for (box_x=0; box_x right) - goto done_with_line; - } - - scanline_address++; - x++; - } - - /* the rest of the line */ - for (; x right) - goto done_with_line; - } - - scanline_address++; - } - -done_with_line:; - - dst_y++; - if (dst_y > bottom) - goto done_with_blit; - } - - /* go to the next line */ - src_y++; - } - -done_with_blit:; - jfree(scanline); -} - -static void merge_zoomed_image16(Image *dst, Image *src, - int x, int y, int opacity, - int blend_mode, int zoom) -{ - BLEND_COLOR blender; - ase_uint16 *src_address; - ase_uint16 *dst_address; - ase_uint16 *scanline, *scanline_address; - int src_x, src_y, src_w, src_h; - int dst_x, dst_y, dst_w, dst_h; - int box_x, box_y, box_w, box_h; - int sizeof_box, offsetx, offsety; - int line_x, line_h, right, bottom; - - blender = GrayscaleTraits::get_blender(blend_mode); - - box_w = 1<w; - src_h = src->h; - - dst_x = x; - dst_y = y; - dst_w = src->w<h<>zoom; - src_w -= (-dst_x)>>zoom; - dst_w -= (-dst_x); - offsetx = box_w - ((-dst_x) % box_w); - dst_x = 0; - } - else - offsetx = 0; - - if (dst_y < 0) { - src_y += (-dst_y)>>zoom; - src_h -= (-dst_y)>>zoom; - dst_h -= (-dst_y); - offsety = box_h - ((-dst_y) % box_h); - dst_y = 0; - } - else - offsety = 0; - - if (dst_x+dst_w > dst->w) { - src_w -= (dst_x+dst_w-dst->w) >> zoom; - dst_w = dst->w - dst_x; - } - - if (dst_y+dst_h > dst->h) { - src_h -= (dst_y+dst_h-dst->h) >> zoom; - dst_h = dst->h - dst_y; - } - - if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0)) - return; - - sizeof_box = sizeof(ase_uint16) * box_w; - right = dst_x+dst_w-1; - bottom = dst_y+dst_h-1; - - scanline = (ase_uint16*)jmalloc(sizeof(ase_uint16) * src_w); - - /* merge process */ - - /* opacity = (opacity)? opacity+1: 0; */ - - for (y=0; yline)[src_y] + src_x; - dst_address = ((ase_uint16 **)dst->line)[dst_y] + dst_x; - scanline_address = scanline; - - /* read `src' and `dst' and blend them, put the result in `scanline' */ - for (x=0; x 0) && (y == 0)) - line_h = offsety; - else - line_h = box_h; - - /* put the line in `dst' */ - for (box_y=0; box_yline)[dst_y] + dst_x; - scanline_address = scanline; - - line_x = dst_x; - x = 0; - - /* first pixel */ - if (offsetx > 0) { - for (box_x=0; box_x right) - goto done_with_line; - } - - scanline_address++; - x++; - } - - /* the rest of the line */ - for (; x right) - goto done_with_line; - } - - scanline_address++; - } - -done_with_line:; - - dst_y++; - if (dst_y > bottom) - goto done_with_blit; - } - - /* go to the next line */ - src_y++; - } - -done_with_blit:; - jfree(scanline); -} - -static void merge_zoomed_image32(Image *dst, Image *src, - int x, int y, int opacity, - int blend_mode, int zoom) -{ - BLEND_COLOR blender; - ase_uint32 *src_address; - ase_uint32 *dst_address; - ase_uint32 *scanline, *scanline_address; - int src_x, src_y, src_w, src_h; - int dst_x, dst_y, dst_w, dst_h; - int box_x, box_y, box_w, box_h; - int sizeof_box, offsetx, offsety; - int line_x, line_h, right, bottom; - - blender = RgbTraits::get_blender(blend_mode); - - box_w = 1<w; - src_h = src->h; - - dst_x = x; - dst_y = y; - dst_w = src->w<h<>zoom; - src_w -= (-dst_x)>>zoom; - dst_w -= (-dst_x); - offsetx = box_w - ((-dst_x) % box_w); - dst_x = 0; - } - else - offsetx = 0; - - if (dst_y < 0) { - src_y += (-dst_y)>>zoom; - src_h -= (-dst_y)>>zoom; - dst_h -= (-dst_y); - offsety = box_h - ((-dst_y) % box_h); - dst_y = 0; - } - else - offsety = 0; - - if (dst_x+dst_w > dst->w) { - src_w -= (dst_x+dst_w-dst->w) >> zoom; - dst_w = dst->w - dst_x; - } - - if (dst_y+dst_h > dst->h) { - src_h -= (dst_y+dst_h-dst->h) >> zoom; - dst_h = dst->h - dst_y; - } - - if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0)) - return; - - sizeof_box = sizeof(ase_uint32) * box_w; - right = dst_x+dst_w-1; - bottom = dst_y+dst_h-1; - - scanline = (ase_uint32*)jmalloc(sizeof(ase_uint32) * src_w); - - /* merge process */ - - /* opacity = (opacity)? opacity+1: 0; */ - - for (y=0; yline)[src_y] + src_x; - dst_address = ((ase_uint32 **)dst->line)[dst_y] + dst_x; - scanline_address = scanline; - - /* read `src' and `dst' and blend them, put the result in `scanline' */ - for (x=0; x 0) && (y == 0)) - line_h = offsety; - else - line_h = box_h; - - /* put the line in `dst' */ - for (box_y=0; box_yline)[dst_y] + dst_x; - scanline_address = scanline; - - line_x = dst_x; - x = 0; - - /* first pixel */ - if (offsetx > 0) { - for (box_x=0; box_x right) - goto done_with_line; - } - - scanline_address++; - x++; - } - - /* the rest of the line */ - for (; x right) - goto done_with_line; - } - - scanline_address++; - } - -done_with_line:; - - dst_y++; - if (dst_y > bottom) - goto done_with_blit; - } - - /* go to the next line */ - src_y++; - } - -done_with_blit:; - jfree(scanline); -}