Skip to content

Commit

Permalink
add mirror()
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Karasik committed Sep 15, 2015
1 parent 8095eea commit c616d58
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 19 deletions.
43 changes: 41 additions & 2 deletions Image.c
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,28 @@ Image_rotate( Handle self, int degrees)
{
Byte * new_data;
int new_line_size;

switch (degrees) {
case 90:
case 270:
case 180:
break;
default:
croak("'degrees' must be 90,180,or 270");
}

if (( var-> type & imBPP) < 8) {
int type = var->type;
my->set_type( self, imbpp8 );
my->rotate( self, degrees );
if ( is_opt( optPreserveType)) {
my-> set_conversion( self, ictNone);
my-> set_type( self, type);
my-> set_conversion( self, var-> conversion);
}
return;
}

switch (degrees) {
case 90:
case 270:
Expand All @@ -1648,8 +1670,6 @@ Image_rotate( Handle self, int degrees)
if (( new_data = allocb( var->dataSize )) == NULL )
croak("Image::rotate: cannot allocate %d bytes", var->dataSize );
break;
default:
croak("'degrees' must be 90,180,or 270");
}

img_rotate( self, new_data, degrees );
Expand All @@ -1666,6 +1686,25 @@ Image_rotate( Handle self, int degrees)
my-> update_change(self);
}

void
Image_mirror( Handle self, Bool vertically)
{
if (!vertically && ( var-> type & imBPP) < 8) {
int type = var->type;
my->set_type( self, imbpp8 );
my->mirror( self, vertically );
if ( is_opt( optPreserveType)) {
my-> set_conversion( self, ictNone);
my-> set_type( self, type);
my-> set_conversion( self, var-> conversion);
}
return;
}

img_mirror( self, vertically );
my-> update_change(self);
}

#ifdef __cplusplus
}
#endif
1 change: 1 addition & 0 deletions Image.cls
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ object Prima::Image( Prima::Drawable)
weird PList load( SV * className, char *filename, HV * profile);
c_only void make_empty();
method void map( Color color);
method void mirror( Bool vertically );
import SV * notification_types();
import SV * profile_default ();
method Bool put_image_indirect( Handle image, int x, int y, int xFrom, int yFrom, int xDestLen, int yDestLen, int xLen, int yLen, int rop);
Expand Down
80 changes: 64 additions & 16 deletions img/rotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ rotate90( PImage i, Byte * new_data, int new_line_size)
Byte * src = i->data, * dst0;

switch (i->type & imBPP) {
case 1: return ;
case 4: return ;

case 8:
dst0 = new_data + i->w * new_line_size;
for ( y = 0; y < i-> h; y++) {
Expand Down Expand Up @@ -58,9 +55,6 @@ rotate180( PImage i, Byte * new_data)
Byte * src = i->data, *dst = new_data + i-> h * i-> lineSize - tail - pixel_size;

switch (i->type & imBPP) {
case 1: return ;
case 4: return ;

case 8:
for ( y = 0; y < i-> h; y++) {
register int x = w;
Expand All @@ -76,7 +70,7 @@ rotate180( PImage i, Byte * new_data)
for ( y = 0; y < i-> h; y++) {
register int x = w;
while (x--) {
register int b = bs2;
register int b = pixel_size;
while ( b--)
*dst++ = *src++;
dst -= bs2;
Expand All @@ -94,36 +88,32 @@ rotate270( PImage i, Byte * new_data, int new_line_size)
int y;
int w = i->w;
int pixel_size = (i-> type & imBPP) / 8;
int tail = i-> lineSize - w * pixel_size ;
int tail = i-> lineSize - w * pixel_size;
Byte * src = i->data, *dst0;

switch (i->type & imBPP) {
case 1: return ;
case 4: return ;

case 8:
dst0 = new_data + i->h - new_line_size - 1;
for ( y = 0; y < i-> h; y++) {
register int x = w;
register Byte * dst = dst0--;
while (x--)
*(dst += new_line_size) = *src++;
*(dst += new_line_size) = *(src++);
src += tail;
}
return;

default:
dst0 = new_data + ( i->h - 1) * pixel_size;
dst0 = new_data + (i->h - 1) * pixel_size;
new_line_size -= pixel_size;
for ( y = 0; y < i-> h; y++) {
register int x = w;
register Byte * dst = dst0;
while (x--) {
register int b = pixel_size;
register int b = pixel_size;
while ( b--)
*dst++ = *src++;
*(dst++) = *(src++);
dst += new_line_size;

}
src += tail;
dst0 -= pixel_size;
Expand All @@ -137,6 +127,9 @@ img_rotate( Handle self, Byte * new_data, int degrees)
{
PImage i = ( PImage ) self;

if (( i-> type & imBPP) < 8 )
croak("Not implemented");

switch ( degrees ) {
case 90:
rotate90(i, new_data, (( i-> h * ( i->type & imBPP) + 31) / 32) * 4);
Expand All @@ -150,6 +143,61 @@ img_rotate( Handle self, Byte * new_data, int degrees)
}
}

void
img_mirror( Handle self, Bool vertically)
{
int y;
PImage i = ( PImage ) self;
int ls = i->lineSize, w = i->w, h = i->h;
register Byte swap;

if ( vertically ) {
Byte * src = i->data, *dst = i->data + ( h - 1 ) * ls, *p, *q, x;
h /= 2;
for ( y = 0; y < h; y++, src += ls, dst -= ls ) {
p = src;
q = dst;
register t = ls;
while ( t-- ) {
swap = *q;
*(q++) = *p;
*(p++) = swap;
}
}
} else {
Byte * data = i->data;
int x, xl, xr, pixel_size = (i->type & imBPP) / 8, last_pixel = (w - 1) * pixel_size, t, w2 = w / 2;
switch (i->type & imBPP) {
case 1:
case 4:
croak("Not implemented");
case 8:
for ( y = 0; y < h; y++, data += ls ) {
Byte *p = data, *q = data + last_pixel;
register int t = w2;
while ( t-- ) {
swap = *q;
*(q--) = *p;
*(p++) = swap;
}
}
break;
default:
for ( y = 0; y < h; y++, data += ls ) {
Byte *p = data, *q = data + last_pixel;
for ( x = 0; x < w2; x++, q -= pixel_size * 2) {
register int t = pixel_size;
while (t--) {
swap = *q;
*(q++) = *p;
*(p++) = swap;
}
}
}
}
}
}

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions pod/Prima/Image.pod
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,10 @@ gray non-8 bit pixel values, by the code:

$image-> resample( $image-> rangeLo, $image-> rangeHi, 0, 255);

=item rotate DEGREES

Rotates the image by 90, 180, or 270 degrees.

=item save (FILENAME or FILEGLOB), [ %PARAMETERS ]

Stores image data into image file FILENAME or stream FILEGLOB, and returns the success flag.
Expand Down
37 changes: 36 additions & 1 deletion t/Image/Transform.t
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use Test::More;
use Prima::Test;
use Prima::Application;

plan tests => 9;
plan tests => 16;

sub bytes { unpack('H*', shift ) }

Expand Down Expand Up @@ -42,3 +42,38 @@ $j->rotate(180);
is( $j->width, 4, "rotate(180) width ok");
is( $j->height, 2, "rotate(180) height ok");
is($j->data, "75318642", "rotate(180) data ok");

my $k = Prima::Image->create(
width => 2,
height => 2,
type => im::Short,
data => "12345678",
lineSize => 4,
);

$k->rotate(270);
is($k->data, "56127834", "short: rotate(270) data ok");

$k->data("12345678");
$k->rotate(90);
is($k->data, "34781256", "short: rotate(90) data ok");

$k->data("12345678");
$k->rotate(180);
is($k->data, "78563412", "short: rotate(180) data ok");

# mirroring
$j->data("12345678");
$j->mirror(1);
is( $j->data, "56781234", "byte: vertical mirroring ok");
$j->data("12345678");
$j->mirror(0);
is( $j->data, "43218765", "byte: horizontal mirroring ok");

$j->type(im::Short);
$j->data("123456789ABCDEFG");
$j->mirror(1);
is( $j->data, "9ABCDEFG12345678", "short: vertical mirroring ok");
$j->data("123456789ABCDEFG");
$j->mirror(0);
is( $j->data, "78563412FGDEBC9A", "short: horizontal mirroring ok");

0 comments on commit c616d58

Please sign in to comment.