Grid-Transform
view release on metacpan or search on metacpan
Transform.xs view on Meta::CPAN
}
/* Add extra empty elements. */
for (i=add+len; i>len; i--) {
AvARRAY(self->grid)[i] = newSVpvn("", 0);
}
RETVAL = self;
OUTPUT:
RETVAL
Grid::Transform
copy (self)
Grid::Transform self
PROTOTYPE: $
PREINIT:
grid_t *copy;
CODE:
New(0, copy, 1, grid_t);
copy->grid = av_make(av_len(self->grid)+1, AvARRAY(self->grid));
copy->rows = self->rows;
copy->columns = self->columns;
copy->dirty = self->dirty;
RETVAL = copy;
OUTPUT:
RETVAL
IV
rows (self, rows=0)
Grid::Transform self
IV rows
PROTOTYPE: $;$
CODE:
if (items == 2) {
self->rows = rows;
self->dirty = 1;
}
RETVAL = self->rows;
OUTPUT:
RETVAL
IV
columns (self, columns=0)
Grid::Transform self
IV columns
PROTOTYPE: $;$
ALIAS:
cols = 1
CODE:
if (items == 2) {
self->columns = columns;
self->dirty = 1;
}
RETVAL = self->columns;
OUTPUT:
RETVAL
void
grid (self, aref=0)
Grid::Transform self
SV *aref
PROTOTYPE: $;\@
PPCODE:
if (items == 2) {
AV *av = (AV *)SvRV(aref);
if (! (SvRV(aref) && SvTYPE(SvRV(aref)) == SVt_PVAV)) {
croak ("reference to an array expected");
}
SvREFCNT_dec(self->grid);
self->grid = av_make(av_len(av)+1, AvARRAY(av));
self->dirty = 1;
}
if (GIMME_V != G_VOID) {
FIX_DIRTY_GRID(self);
if (GIMME_V == G_ARRAY) {
IV i, len = av_len(self->grid);
EXTEND(SP, len + 1);
for (i=0; i<=len; i++) {
PUSHs(sv_2mortal(SvREFCNT_inc(AvARRAY(self->grid)[i])));
}
}
else {
PUSHs(sv_2mortal(newRV_inc((SV *)self->grid)));
}
}
void
rotate_180 (self)
Grid::Transform self
PROTOTYPE: $
ALIAS:
rotate180 = 1
PPCODE:
FIX_DIRTY_GRID(self);
REVERSE_AV(self->grid);
XSRETURN(1);
void
rotate_90 (self)
Grid::Transform self
PROTOTYPE: $
ALIAS:
rotate90 = 1
PREINIT:
SV **tmp;
IV n, i, row, col;
PPCODE:
FIX_DIRTY_GRID(self);
n = self->rows * self->columns;
New(0, tmp, n, SV*);
for (i=0, col=0; col<self->columns; col++) {
for (row=self->rows-1; row>=0; row--, i++) {
tmp[i] = AvARRAY(self->grid)[col + row * self->columns];
}
}
for (i=0; i<n; i++) {
AvARRAY(self->grid)[i] = tmp[i];
}
Safefree(tmp);
SWAP(IV, self->rows, self->columns);
XSRETURN(1);
void
rotate_270 (self)
Grid::Transform self
PROTOTYPE: $
ALIAS:
rotate270 = 1
PREINIT:
SV **tmp;
IV n, i, row, col;
PPCODE:
FIX_DIRTY_GRID(self);
n = self->rows * self->columns;
New(0, tmp, n, SV*);
for (i=0, col=self->columns-1; col>=0; col--) {
for (row=0; row<self->rows; row++, i++) {
tmp[i] = AvARRAY(self->grid)[col + row * self->columns];
}
}
for (i=0; i<n; i++) {
AvARRAY(self->grid)[i] = tmp[i];
}
Safefree(tmp);
SWAP(IV, self->rows, self->columns);
XSRETURN(1);
void
transpose (self)
Grid::Transform self
PROTOTYPE: $
PREINIT:
SV **tmp;
IV n, i, row, col;
PPCODE:
FIX_DIRTY_GRID(self);
n = self->rows * self->columns;
New(0, tmp, n, SV*);
for (i=0, col=self->columns-1; col>=0; col--) {
for (row=self->rows-1; row>=0; row--, i++) {
tmp[i] = AvARRAY(self->grid)[col + row * self->columns];
}
}
for (i=0; i<n; i++) {
AvARRAY(self->grid)[i] = tmp[i];
}
Safefree(tmp);
SWAP(IV, self->rows, self->columns);
XSRETURN(1);
void
counter_transpose (self)
Grid::Transform self
PROTOTYPE: $
ALIAS:
countertranspose = 1
PREINIT:
SV **tmp;
IV n, i, row, col;
PPCODE:
FIX_DIRTY_GRID(self);
n = self->rows * self->columns;
New(0, tmp, n, SV*);
for (i=0, col=0; col<self->columns; col++) {
for (row=0; row<self->rows; row++, i++) {
tmp[i] = AvARRAY(self->grid)[col + row * self->columns];
}
}
for (i=0; i<n; i++) {
AvARRAY(self->grid)[i] = tmp[i];
}
Safefree(tmp);
SWAP(IV, self->rows, self->columns);
XSRETURN(1);
void
flip_horizontal (self)
Grid::Transform self
PROTOTYPE: $
ALIAS:
mirror_horizontal = 1
PREINIT:
IV row, lcol, rcol;
PPCODE:
FIX_DIRTY_GRID(self);
for (row=0; row<self->rows; row++) {
for (lcol=0, rcol=self->columns-1; lcol<rcol; lcol++, rcol--) {
SWAP(SV*, AvARRAY(self->grid)[lcol + row * self->columns],
AvARRAY(self->grid)[rcol + row * self->columns]);
}
}
XSRETURN(1);
void
flip_vertical (self)
Grid::Transform self
PROTOTYPE: $
ALIAS:
mirror_vertical = 1
PREINIT:
IV col, trow, brow;
PPCODE:
FIX_DIRTY_GRID(self);
for (col=0; col<self->columns; col++) {
for (trow=0, brow=self->rows-1; trow<brow; trow++, brow--) {
SWAP(SV*, AvARRAY(self->grid)[col + trow * self->columns],
AvARRAY(self->grid)[col + brow * self->columns]);
}
}
XSRETURN(1);
void fold_right (self)
Grid::Transform self
PROTOTYPE: $
PREINIT:
SV **tmp;
IV n, i, row, col, h;
PPCODE:
FIX_DIRTY_GRID(self);
n = self->rows * self->columns;
New(0, tmp, n, SV*);
h = self->columns >> 1;
for (i=0, row=0; row<self->rows; row++) {
IV cn = row * self->columns;
if (self->columns & 1) {
tmp[i++] = AvARRAY(self->grid)[h + cn];
}
for (col=h-1; col>=0; col--) {
tmp[i++] = AvARRAY(self->grid)[col + cn];
tmp[i++] = AvARRAY(self->grid)[self->columns - 1 - col + cn];
}
}
for (i=0; i<n; i++) {
AvARRAY(self->grid)[i] = tmp[i];
}
Safefree(tmp);
XSRETURN(1);
void fold_left (self)
Grid::Transform self
PROTOTYPE: $
PREINIT:
SV **tmp;
IV n, i, row, col, h;
PPCODE:
FIX_DIRTY_GRID(self);
n = self->rows * self->columns;
New(0, tmp, n, SV*);
h = self->columns >> 1;
for (i=0, row=0; row<self->rows; row++) {
IV cn = row * self->columns;
for (col=0; col<h; col++) {
tmp[i++] = AvARRAY(self->grid)[self->columns - 1 - col + cn];
tmp[i++] = AvARRAY(self->grid)[col + cn];
}
if (self->columns & 1) {
tmp[i++] = AvARRAY(self->grid)[h + cn];
}
}
for (i=0; i<n; i++) {
AvARRAY(self->grid)[i] = tmp[i];
}
Safefree(tmp);
XSRETURN(1);
void alternate_row_direction (self)
Grid::Transform self
PROTOTYPE: $
ALIAS:
alt_row_dir = 1
PREINIT:
IV row, lcol, rcol;
PPCODE:
FIX_DIRTY_GRID(self);
for (row=1; row<self->rows; row+=2) {
for (lcol=0, rcol=self->columns-1; lcol<rcol; lcol++, rcol--) {
SWAP(SV*, AvARRAY(self->grid)[lcol + row * self->columns],
AvARRAY(self->grid)[rcol + row * self->columns]);
}
}
XSRETURN(1);
void spiral (self)
Grid::Transform self
PROTOTYPE: $
PREINIT:
SV **tmp;
IV n, i, idx, top, bottom, left, right;
PPCODE:
FIX_DIRTY_GRID(self);
n = self->rows * self->columns;
New(0, tmp, n, SV*);
idx = 0;
top = 0;
bottom = self->rows-1;
left = 0;
right = self->columns-1;
while (1) {
for (i=left; i<=right; i++) {
tmp[idx++] = AvARRAY(self->grid)[i + top * self->columns];
}
if (++top > bottom) break;
for (i=top; i<=bottom; i++) {
tmp[idx++] = AvARRAY(self->grid)[right + i * self->columns];
}
if (--right < left) break;
for (i=right; i>=left; i--) {
tmp[idx++] = AvARRAY(self->grid)[i + bottom * self->columns];
}
if (--bottom < top) break;
for (i=bottom; i>=top; i--) {
tmp[idx++] = AvARRAY(self->grid)[left + i * self->columns];
}
if (++left > right) break;
}
for (i=0; i<n; i++) {
AvARRAY(self->grid)[i] = tmp[i];
}
Safefree(tmp);
XSRETURN(1);
void
DESTROY (self)
Grid::Transform self
CODE:
if (self->grid) {
SvREFCNT_dec(self->grid);
}
Safefree(self);
( run in 1.202 second using v1.01-cache-2.11-cpan-5511b514fd6 )