Assume unpremultiplied input in all cases. Reformat.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@14335 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Alexander Malmberg 2002-08-26 14:36:43 +00:00
parent a35bc00d50
commit a008e3d919
2 changed files with 347 additions and 327 deletions

View file

@ -1,3 +1,9 @@
2002-08-26 16:36 Alexander Malmberg <alexander@malmberg.org>
* Source/art/image.m: Assume that input isn't premultiplied in
all cases (to match -xlib behavior, for now). Reformat to fit
coding standards better.
2002-08-26 15:59 Alexander Malmberg <alexander@malmberg.org> 2002-08-26 15:59 Alexander Malmberg <alexander@malmberg.org>
* Headers/art/ARTContext.h, Source/art/ARTContext.m, * Headers/art/ARTContext.h, Source/art/ARTContext.m,

View file

@ -33,7 +33,8 @@ Image drawing. DPSimage and helpers.
#include "blit.h" #include "blit.h"
static unsigned int _get_8_bits(const unsigned char *ptr,int bit_ofs,int num_bits) static unsigned int _get_8_bits(const unsigned char *ptr, int bit_ofs,
int num_bits)
{ {
/* /*
TODO: if we get values with more than 8 bits, we should round properly and TODO: if we get values with more than 8 bits, we should round properly and
@ -41,44 +42,45 @@ not just discard the extra bits
*/ */
int i; int i;
unsigned int v; unsigned int v;
ptr+=bit_ofs/8; ptr += bit_ofs / 8;
bit_ofs%=8; bit_ofs %= 8;
v=0; v = 0;
for (i=0;i<8 && i<num_bits;i++) for (i = 0; i < 8 && i < num_bits; i++)
{ {
v<<=1; v <<= 1;
if ((*ptr)&(128>>bit_ofs)) if ((*ptr) & (128 >> bit_ofs))
v|=1; v |= 1;
bit_ofs++; bit_ofs++;
if (bit_ofs==8) if (bit_ofs == 8)
{ {
ptr++; ptr++;
bit_ofs=0; bit_ofs = 0;
} }
} }
/* extend what we've got to 8 bits */
switch (num_bits) switch (num_bits)
{ {
case 1: case 1:
v*=255; v *= 255;
break; break;
case 2: case 2:
v*=85; v *= 85;
break; break;
case 3: case 3:
v=(v<<5)|(v<<2)|(v>>1); v = (v << 5) | (v << 2) | (v >> 1);
break; break;
case 4: case 4:
v=(v<<4)|v; v = (v << 4) | v;
break; break;
case 5: case 5:
v=(v<<3)|(v>>2); v = (v << 3) | (v >> 2);
break; break;
case 6: case 6:
v=(v<<2)|(v>>4); v = (v << 2) | (v >> 4);
break; break;
case 7: case 7:
v=(v<<1)|(v>>6); v = (v << 1) | (v >> 6);
break; break;
} }
return v; return v;
@ -87,9 +89,9 @@ not just discard the extra bits
typedef struct typedef struct
{ {
int width,height; int width, height;
int bits_per_sample,samples_per_pixel,bits_per_pixel,bytes_per_row; int bits_per_sample, samples_per_pixel, bits_per_pixel, bytes_per_row;
BOOL is_planar,has_alpha; BOOL is_planar, has_alpha;
const unsigned char **data; const unsigned char **data;
/* /*
@ -103,352 +105,358 @@ typedef struct
} image_info_t; } image_info_t;
static void _image_get_color_rgb_8(image_info_t *ii,render_run_t *ri,int x,int y) static void _image_get_color_rgb_8(image_info_t *ii, render_run_t *ri,
int x, int y)
{ {
int ofs; int ofs;
if (x<0) x=0; if (x < 0) x = 0;
if (y<0) y=0; if (y < 0) y = 0;
if (x>=ii->width) x=ii->width-1; if (x >= ii->width) x = ii->width - 1;
if (x>=ii->height) y=ii->height-1; if (x >= ii->height) y = ii->height - 1;
ofs=ii->bytes_per_row*y+x*ii->bits_per_pixel/8; ofs = ii->bytes_per_row * y + x * ii->bits_per_pixel / 8;
if (ii->is_planar) if (ii->is_planar)
{ {
ri->r=ii->data[0][ofs]; ri->r = ii->data[0][ofs];
ri->g=ii->data[1][ofs]; ri->g = ii->data[1][ofs];
ri->b=ii->data[2][ofs]; ri->b = ii->data[2][ofs];
if (ii->has_alpha) if (ii->has_alpha)
ri->a=ii->data[3][ofs]; ri->a = ii->data[3][ofs];
else else
ri->a=255; ri->a = 255;
} }
else else
{ {
ri->r=ii->data[0][ofs]; ri->r = ii->data[0][ofs];
ri->g=ii->data[0][ofs+1]; ri->g = ii->data[0][ofs + 1];
ri->b=ii->data[0][ofs+2]; ri->b = ii->data[0][ofs + 2];
if (ii->has_alpha) if (ii->has_alpha)
ri->a=ii->data[0][ofs+3]; ri->a = ii->data[0][ofs + 3];
else else
ri->a=255; ri->a = 255;
} }
} }
static void _image_get_color_rgb_cmyk_gray(image_info_t *ii,render_run_t *ri,int x,int y) static void _image_get_color_rgb_cmyk_gray(image_info_t *ii, render_run_t *ri,
int x, int y)
{ {
int ofs,bit_ofs; int ofs, bit_ofs;
int values[5]; int values[5];
int i,j; int i, j;
if (x<0) x=0; if (x < 0) x = 0;
if (y<0) y=0; if (y < 0) y = 0;
if (x>=ii->width) x=ii->width-1; if (x >= ii->width) x = ii->width - 1;
if (x>=ii->height) y=ii->height-1; if (x >= ii->height) y = ii->height - 1;
ofs=y*ii->bytes_per_row; ofs = y * ii->bytes_per_row;
bit_ofs=x*ii->bits_per_pixel; bit_ofs = x * ii->bits_per_pixel;
for (i=j=0;i<ii->samples_per_pixel;i++) for (i = j = 0; i < ii->samples_per_pixel; i++)
{ {
values[i]=_get_8_bits(ii->data[j]+ofs,bit_ofs,ii->bits_per_sample); values[i] = _get_8_bits(ii->data[j] + ofs, bit_ofs, ii->bits_per_sample);
if (ii->is_planar) if (ii->is_planar)
j++; j++;
else else
bit_ofs+=ii->bits_per_sample; bit_ofs += ii->bits_per_sample;
} }
if (ii->has_alpha) if (ii->has_alpha)
ri->a=values[i-1]; ri->a = values[i - 1];
else else
ri->a=255; ri->a = 255;
if (ii->colorspace==1) if (ii->colorspace == 1)
{ {
ri->r=values[0]; ri->r = values[0];
ri->g=values[1]; ri->g = values[1];
ri->b=values[2]; ri->b = values[2];
} }
else if (ii->colorspace==2) else if (ii->colorspace == 2)
{ {
j=255-values[0]-values[3]; j = 255 - values[0] - values[3];
ri->r=j<0?0:j; ri->r = j < 0?0:j;
j=255-values[1]-values[3]; j = 255 - values[1] - values[3];
ri->g=j<0?0:j; ri->g = j < 0?0:j;
j=255-values[2]-values[3]; j = 255 - values[2] - values[3];
ri->b=j<0?0:j; ri->b = j < 0?0:j;
} }
else if (ii->colorspace==3) else if (ii->colorspace == 3)
{ {
ri->r=ri->g=ri->b=values[0]; ri->r = ri->g = ri->b = values[0];
} }
} }
@implementation ARTGState (image) @implementation ARTGState (image)
-(void) _image_do_rgb_transform: (image_info_t *)ii : (NSAffineTransform *)matrix -(void) _image_do_rgb_transform: (image_info_t *)ii
: (void (*)(image_info_t *ii,render_run_t *ri,int x,int y))ifunc : (NSAffineTransform *)matrix
: (void (*)(image_info_t *ii, render_run_t *ri, int x, int y))ifunc
{ {
/* /*
TODO: TODO:
seems to have problems with rotations. 0, 90, 180, 270 work fine, but others seems to have problems with rotations. 0, 90, 180, 270 work fine, but others
seem to cause edges to be off by a pixel seem to cause edges to be off by a pixel
*/ */
int x[4],y[4]; int x[4], y[4];
int tx[4],ty[4]; int tx[4], ty[4];
float fx[4],fy[4]; float fx[4], fy[4];
int cy,ey; int cy, ey;
int left_delta,next; int left_delta, next;
int lx,lx_frac,ldx,ldx_frac,l_de,le; int lx, lx_frac, ldx, ldx_frac, l_de, le;
int rx,rx_frac,rdx,rdx_frac,r_de,re; int rx, rx_frac, rdx, rdx_frac, r_de, re;
int ltx,lty,ltx_frac,lty_frac,ldtx,ldty,ldtx_frac,ldty_frac; int ltx, lty, ltx_frac, lty_frac, ldtx, ldty, ldtx_frac, ldty_frac;
int rtx,rty,rtx_frac,rty_frac,rdtx,rdty,rdtx_frac,rdty_frac; int rtx, rty, rtx_frac, rty_frac, rdtx, rdty, rdtx_frac, rdty_frac;
NSPoint p; NSPoint p;
p=[matrix transformPoint: NSMakePoint(0,0)]; p = [matrix transformPoint: NSMakePoint(0, 0)];
fx[0]=p.x; fy[0]=p.y; fx[0] = p.x; fy[0] = p.y;
p=[matrix transformPoint: NSMakePoint(ii->width,0)]; p = [matrix transformPoint: NSMakePoint(ii->width, 0)];
fx[1]=p.x; fy[1]=p.y; fx[1] = p.x; fy[1] = p.y;
p=[matrix transformPoint: NSMakePoint(ii->width,ii->height)]; p = [matrix transformPoint: NSMakePoint(ii->width, ii->height)];
fx[2]=p.x; fy[2]=p.y; fx[2] = p.x; fy[2] = p.y;
p=[matrix transformPoint: NSMakePoint(0,ii->height)]; p = [matrix transformPoint: NSMakePoint(0, ii->height)];
fx[3]=p.x; fy[3]=p.y; fx[3] = p.x; fy[3] = p.y;
if (fabs(fx[0]-floor(fx[0]+.5))<0.001) fx[0]=floor(fx[0]+.5); if (fabs(fx[0] - floor(fx[0] + .5)) < 0.001) fx[0] = floor(fx[0] + .5);
if (fabs(fx[1]-floor(fx[1]+.5))<0.001) fx[1]=floor(fx[1]+.5); if (fabs(fx[1] - floor(fx[1] + .5)) < 0.001) fx[1] = floor(fx[1] + .5);
if (fabs(fx[2]-floor(fx[2]+.5))<0.001) fx[2]=floor(fx[2]+.5); if (fabs(fx[2] - floor(fx[2] + .5)) < 0.001) fx[2] = floor(fx[2] + .5);
if (fabs(fx[3]-floor(fx[3]+.5))<0.001) fx[3]=floor(fx[3]+.5); if (fabs(fx[3] - floor(fx[3] + .5)) < 0.001) fx[3] = floor(fx[3] + .5);
if (fabs(fy[0]-floor(fy[0]+.5))<0.001) fy[0]=floor(fy[0]+.5); if (fabs(fy[0] - floor(fy[0] + .5)) < 0.001) fy[0] = floor(fy[0] + .5);
if (fabs(fy[1]-floor(fy[1]+.5))<0.001) fy[1]=floor(fy[1]+.5); if (fabs(fy[1] - floor(fy[1] + .5)) < 0.001) fy[1] = floor(fy[1] + .5);
if (fabs(fy[2]-floor(fy[2]+.5))<0.001) fy[2]=floor(fy[2]+.5); if (fabs(fy[2] - floor(fy[2] + .5)) < 0.001) fy[2] = floor(fy[2] + .5);
if (fabs(fy[3]-floor(fy[3]+.5))<0.001) fy[3]=floor(fy[3]+.5); if (fabs(fy[3] - floor(fy[3] + .5)) < 0.001) fy[3] = floor(fy[3] + .5);
x[0]=floor(fx[0]); y[0]=wi->sy-floor(fy[0]); x[0] = floor(fx[0]); y[0] = wi->sy - floor(fy[0]);
x[1]=floor(fx[1]); y[1]=wi->sy-floor(fy[1]); x[1] = floor(fx[1]); y[1] = wi->sy - floor(fy[1]);
x[2]=floor(fx[2]); y[2]=wi->sy-floor(fy[2]); x[2] = floor(fx[2]); y[2] = wi->sy - floor(fy[2]);
x[3]=floor(fx[3]); y[3]=wi->sy-floor(fy[3]); x[3] = floor(fx[3]); y[3] = wi->sy - floor(fy[3]);
tx[0]=0; ty[0]=ii->height; tx[0] = 0; ty[0] = ii->height;
tx[1]=ii->width; ty[1]=ii->height; tx[1] = ii->width; ty[1] = ii->height;
tx[2]=ii->width; ty[2]=0; tx[2] = ii->width; ty[2] = 0;
tx[3]=0; ty[3]=0; tx[3] = 0; ty[3] = 0;
cy=y[le=0]; cy = y[le = 0];
if (y[1]<cy) cy=y[le=1]; if (y[1] < cy) cy = y[le = 1];
if (y[2]<cy) cy=y[le=2]; if (y[2] < cy) cy = y[le = 2];
if (y[3]<cy) cy=y[le=3]; if (y[3] < cy) cy = y[le = 3];
re=le; re = le;
ey=y[0]; ey = y[0];
if (y[1]>ey) ey=y[1]; if (y[1] > ey) ey = y[1];
if (y[2]>ey) ey=y[2]; if (y[2] > ey) ey = y[2];
if (y[3]>ey) ey=y[3]; if (y[3] > ey) ey = y[3];
if (x[(le+1)&3]<x[(le-1)&3]) if (x[(le + 1) & 3] < x[(le - 1) & 3])
left_delta=1; left_delta = 1;
else else
left_delta=-1; left_delta = -1;
/* silence the compiler */ /* silence the compiler */
lx=lx_frac=ldx=ldx_frac=l_de=0; lx = lx_frac = ldx = ldx_frac = l_de = 0;
rx=rx_frac=rdx=rdx_frac=r_de=0; rx = rx_frac = rdx = rdx_frac = r_de = 0;
ltx=lty=ltx_frac=lty_frac=ldtx=ldty=ldtx_frac=ldty_frac=0; ltx = lty = ltx_frac = lty_frac = ldtx = ldty = ldtx_frac = ldty_frac = 0;
rtx=rty=rtx_frac=rty_frac=rdtx=rdty=rdtx_frac=rdty_frac=0; rtx = rty = rtx_frac = rty_frac = rdtx = rdty = rdtx_frac = rdty_frac = 0;
while (cy<=ey && cy<clip_y1) while (cy <= ey && cy < clip_y1)
{ {
if (cy==y[le]) if (cy == y[le])
{ {
next=(le+left_delta)&3; next = (le + left_delta) & 3;
while (y[le]==y[next]) while (y[le] == y[next])
{ {
le=next; le = next;
next=(le+left_delta)&3; next = (le + left_delta) & 3;
} }
l_de=y[next]-y[le]; l_de = y[next] - y[le];
lx=x[le]; lx = x[le];
lx_frac=0; lx_frac = 0;
ldx=(x[next]-x[le])/l_de; ldx = (x[next] - x[le]) / l_de;
ldx_frac=(x[next]-x[le])%l_de; ldx_frac = (x[next] - x[le]) % l_de;
ltx=tx[le]; ltx = tx[le];
lty=ty[le]; lty = ty[le];
ltx_frac=0; ltx_frac = 0;
lty_frac=0; lty_frac = 0;
ldtx=(tx[next]-tx[le])/l_de; ldtx = (tx[next] - tx[le]) / l_de;
ldty=(ty[next]-ty[le])/l_de; ldty = (ty[next] - ty[le]) / l_de;
ldtx_frac=(tx[next]-tx[le])%l_de; ldtx_frac = (tx[next] - tx[le]) % l_de;
ldty_frac=(ty[next]-ty[le])%l_de; ldty_frac = (ty[next] - ty[le]) % l_de;
le=next; le = next;
} }
else else
{ {
lx+=ldx; lx += ldx;
lx_frac+=ldx_frac; lx_frac += ldx_frac;
if (lx_frac<0) if (lx_frac < 0)
lx--,lx_frac+=l_de; lx--, lx_frac += l_de;
if (lx_frac>l_de) if (lx_frac > l_de)
lx++,lx_frac-=l_de; lx++, lx_frac -= l_de;
ltx+=ldtx; ltx += ldtx;
ltx_frac+=ldtx_frac; ltx_frac += ldtx_frac;
if (ltx_frac<0) if (ltx_frac < 0)
ltx--,ltx_frac+=l_de; ltx--, ltx_frac += l_de;
if (ltx_frac>l_de) if (ltx_frac > l_de)
ltx++,ltx_frac-=l_de; ltx++, ltx_frac -= l_de;
lty+=ldty; lty += ldty;
lty_frac+=ldty_frac; lty_frac += ldty_frac;
if (lty_frac<0) if (lty_frac < 0)
lty--,lty_frac+=l_de; lty--, lty_frac += l_de;
if (lty_frac>l_de) if (lty_frac > l_de)
lty++,lty_frac-=l_de; lty++, lty_frac -= l_de;
} }
if (cy==y[re]) if (cy == y[re])
{ {
next=(re-left_delta)&3; next = (re - left_delta) & 3;
while (y[re]==y[next]) while (y[re] == y[next])
{ {
re=next; re = next;
next=(re-left_delta)&3; next = (re - left_delta) & 3;
} }
r_de=y[next]-y[re]; r_de = y[next] - y[re];
rx=x[re]; rx = x[re];
rx_frac=r_de-1; /* TODO? */ rx_frac = r_de - 1; /* TODO? */
rdx=(x[next]-x[re])/r_de; rdx = (x[next] - x[re]) / r_de;
rdx_frac=(x[next]-x[re])%r_de; rdx_frac = (x[next] - x[re]) % r_de;
rtx=tx[re]; rtx = tx[re];
rty=ty[re]; rty = ty[re];
rtx_frac=0; rtx_frac = 0;
rty_frac=0; rty_frac = 0;
rdtx=(tx[next]-tx[re])/r_de; rdtx = (tx[next] - tx[re]) / r_de;
rdty=(ty[next]-ty[re])/r_de; rdty = (ty[next] - ty[re]) / r_de;
rdtx_frac=(tx[next]-tx[re])%r_de; rdtx_frac = (tx[next] - tx[re]) % r_de;
rdty_frac=(ty[next]-ty[re])%r_de; rdty_frac = (ty[next] - ty[re]) % r_de;
re=next; re = next;
} }
else else
{ {
rx+=rdx; rx += rdx;
rx_frac+=rdx_frac; rx_frac += rdx_frac;
if (rx_frac<0) if (rx_frac < 0)
rx--,rx_frac+=r_de; rx--, rx_frac += r_de;
if (rx_frac>r_de) if (rx_frac > r_de)
rx++,rx_frac-=r_de; rx++, rx_frac -= r_de;
rtx+=rdtx; rtx += rdtx;
rtx_frac+=rdtx_frac; rtx_frac += rdtx_frac;
if (rtx_frac<0) if (rtx_frac < 0)
rtx--,rtx_frac+=r_de; rtx--, rtx_frac += r_de;
if (rtx_frac>r_de) if (rtx_frac > r_de)
rtx++,rtx_frac-=r_de; rtx++, rtx_frac -= r_de;
rty+=rdty; rty += rdty;
rty_frac+=rdty_frac; rty_frac += rdty_frac;
if (rty_frac<0) if (rty_frac < 0)
rty--,rty_frac+=r_de; rty--, rty_frac += r_de;
if (rty_frac>r_de) if (rty_frac > r_de)
rty++,rty_frac-=r_de; rty++, rty_frac -= r_de;
} }
if (cy>=clip_y0 && rx>lx) if (cy >= clip_y0 && rx > lx)
{ {
render_run_t ri; render_run_t ri;
int x0,x1,de; int x0, x1, de;
int tx,ty,tx_frac,ty_frac,dtx,dty,dtx_frac,dty_frac; int tx, ty, tx_frac, ty_frac, dtx, dty, dtx_frac, dty_frac;
int delta; int delta;
x0=lx; x0 = lx;
x1=rx; x1 = rx;
de=x1-x0; de = x1 - x0;
tx=ltx; tx = ltx;
ty=lty; ty = lty;
tx_frac=ltx_frac*de*r_de; tx_frac = ltx_frac * de * r_de;
ty_frac=lty_frac*de*r_de; ty_frac = lty_frac * de * r_de;
de*=r_de*l_de; de *= r_de * l_de;
delta=(rtx*r_de+rtx_frac)*l_de-(ltx*l_de+ltx_frac)*r_de; delta = (rtx * r_de + rtx_frac) * l_de
dtx=delta/de; - (ltx * l_de + ltx_frac) * r_de;
dtx_frac=delta%de; dtx = delta / de;
dtx_frac = delta % de;
delta=(rty*r_de+rty_frac)*l_de-(lty*l_de+lty_frac)*r_de; delta = (rty * r_de + rty_frac) * l_de
dty=delta/de; - (lty * l_de + lty_frac) * r_de;
dty_frac=delta%de; dty = delta / de;
dty_frac = delta % de;
/* /*
x0 x1/x2 -> y0 y1/y2 z x0 x1 / x2 -> y0 y1 / y2 z
((y0*y2+y1)*x2-(x0*x2+x1)*y2)/(x2*y2*z) ((y0 * y2 + y1) * x2 - (x0 * x2 + x1) * y2) / (x2 * y2 * z)
*/ */
if (x0<clip_x0) if (x0 < clip_x0)
{ {
tx+=dtx*(clip_x0-x0); tx += dtx * (clip_x0 - x0);
ty+=dty*(clip_x0-x0); ty += dty * (clip_x0 - x0);
tx_frac+=dtx_frac*(clip_x0-x0); tx_frac += dtx_frac * (clip_x0 - x0);
while (tx_frac<0) while (tx_frac < 0)
tx--,tx_frac+=de; tx--, tx_frac += de;
while (tx_frac>=de) while (tx_frac >= de)
tx++,tx_frac-=de; tx++, tx_frac -= de;
ty_frac+=dty_frac*(clip_x0-x0); ty_frac += dty_frac * (clip_x0 - x0);
while (ty_frac<0) while (ty_frac < 0)
ty--,ty_frac+=de; ty--, ty_frac += de;
while (ty_frac>=de) while (ty_frac >= de)
ty++,ty_frac-=de; ty++, ty_frac -= de;
x0=clip_x0; x0 = clip_x0;
} }
if (x1>=clip_x1) x1=clip_x1-1; if (x1 >= clip_x1) x1 = clip_x1 - 1;
ri.dst=wi->data+x0*DI.bytes_per_pixel+cy*wi->bytes_per_line; ri.dst = wi->data + x0 * DI.bytes_per_pixel
ri.dsta=wi->alpha+x0+cy*wi->sx; + cy * wi->bytes_per_line;
ri.dsta = wi->alpha + x0 + cy * wi->sx;
if (wi->has_alpha) if (wi->has_alpha)
{ {
for (;x0<x1;x0++,ri.dst+=DI.bytes_per_pixel,ri.dsta++) for (; x0 < x1; x0++, ri.dst += DI.bytes_per_pixel, ri.dsta++)
{ {
ifunc(ii,&ri,tx,ty); ifunc(ii, &ri, tx, ty);
RENDER_RUN_ALPHA_A(&ri,1); RENDER_RUN_ALPHA_A(&ri, 1);
tx+=dtx; tx += dtx;
ty+=dty; ty += dty;
tx_frac+=dtx_frac; tx_frac += dtx_frac;
if (tx_frac<0) if (tx_frac < 0)
tx--,tx_frac+=de; tx--, tx_frac += de;
if (tx_frac>=de) if (tx_frac >= de)
tx++,tx_frac-=de; tx++, tx_frac -= de;
ty_frac+=dty_frac; ty_frac += dty_frac;
if (ty_frac<0) if (ty_frac < 0)
ty--,ty_frac+=de; ty--, ty_frac += de;
if (ty_frac>=de) if (ty_frac >= de)
ty++,ty_frac-=de; ty++, ty_frac -= de;
} }
} }
else else
{ {
for (;x0<x1;x0++,ri.dst+=DI.bytes_per_pixel) for (; x0 < x1; x0++, ri.dst += DI.bytes_per_pixel)
{ {
ifunc(ii,&ri,tx,ty); ifunc(ii, &ri, tx, ty);
RENDER_RUN_ALPHA(&ri,1); RENDER_RUN_ALPHA(&ri, 1);
tx+=dtx; tx += dtx;
ty+=dty; ty += dty;
tx_frac+=dtx_frac; tx_frac += dtx_frac;
if (tx_frac<0) if (tx_frac < 0)
tx--,tx_frac+=de; tx--, tx_frac += de;
if (tx_frac>=de) if (tx_frac >= de)
tx++,tx_frac-=de; tx++, tx_frac -= de;
ty_frac+=dty_frac; ty_frac += dty_frac;
if (ty_frac<0) if (ty_frac < 0)
ty--,ty_frac+=de; ty--, ty_frac += de;
if (ty_frac>=de) if (ty_frac >= de)
ty++,ty_frac-=de; ty++, ty_frac -= de;
} }
} }
} }
@ -458,152 +466,158 @@ seem to cause edges to be off by a pixel
} }
- (void)DPSimage: (NSAffineTransform*) matrix - (void)DPSimage: (NSAffineTransform * ) matrix
: (int) pixelsWide : (int) pixelsHigh : (int) pixelsWide : (int) pixelsHigh
: (int) bitsPerSample : (int) samplesPerPixel : (int) bitsPerSample : (int) samplesPerPixel
: (int) bitsPerPixel : (int) bytesPerRow : (BOOL) isPlanar : (int) bitsPerPixel : (int) bytesPerRow : (BOOL) isPlanar
: (BOOL) hasAlpha : (NSString *) colorSpaceName : (BOOL) hasAlpha : (NSString *) colorSpaceName
: (const unsigned char *const [5]) data : (const unsigned char *const [5]) data
{ {
BOOL identity_transform,is_rgb; BOOL identity_transform, is_rgb;
image_info_t ii; image_info_t ii;
if (!wi || !wi->data) return; if (!wi || !wi->data) return;
if (all_clipped) return; if (all_clipped) return;
[matrix prependTransform: ctm]; [matrix prependTransform: ctm];
if (fabs(matrix->matrix.m11-1.0)<0.001 && fabs(matrix->matrix.m12)<0.001 && if (fabs(matrix->matrix.m11 - 1.0) < 0.001 &&
fabs(matrix->matrix.m22-1.0)<0.001 && fabs(matrix->matrix.m21)<0.001) fabs(matrix->matrix.m12) < 0.001 &&
identity_transform=YES; fabs(matrix->matrix.m22 - 1.0) < 0.001 &&
fabs(matrix->matrix.m21) < 0.001)
identity_transform = YES;
else else
identity_transform=NO; identity_transform = NO;
if (colorSpaceName==NSDeviceRGBColorSpace || if (colorSpaceName == NSDeviceRGBColorSpace ||
colorSpaceName==NSCalibratedRGBColorSpace) colorSpaceName == NSCalibratedRGBColorSpace)
is_rgb=YES; is_rgb = YES;
else else
is_rgb=NO; is_rgb = NO;
/* optimize common case */ /* optimize common case */
if (identity_transform && is_rgb && if (identity_transform && is_rgb &&
bitsPerSample==8 && !isPlanar && bytesPerRow==samplesPerPixel*pixelsWide && bitsPerSample == 8 && !isPlanar &&
((samplesPerPixel==3 && bitsPerPixel==24 && !hasAlpha) || bytesPerRow == samplesPerPixel * pixelsWide &&
(samplesPerPixel==4 && bitsPerPixel==32 && hasAlpha))) ((samplesPerPixel == 3 && bitsPerPixel == 24 && !hasAlpha) ||
(samplesPerPixel == 4 && bitsPerPixel == 32 && hasAlpha)))
{ {
int x,y,ox,oy; int x, y, ox, oy;
const unsigned char *src=data[0]; const unsigned char *src = data[0];
unsigned char *alpha_dest; unsigned char *alpha_dest;
render_run_t ri; render_run_t ri;
if (wi->has_alpha) if (wi->has_alpha)
{ {
if (DI.inline_alpha) if (DI.inline_alpha)
alpha_dest=wi->data+DI.inline_alpha_ofs; alpha_dest = wi->data + DI.inline_alpha_ofs;
else else
alpha_dest=wi->alpha; alpha_dest = wi->alpha;
} }
else else
alpha_dest=NULL; alpha_dest = NULL;
ox=[matrix transformPoint: NSMakePoint(0,0)].x; ox = [matrix transformPoint: NSMakePoint(0, 0)].x;
oy=wi->sy-[matrix transformPoint: NSMakePoint(0,0)].y-pixelsHigh; oy = wi->sy - [matrix transformPoint: NSMakePoint(0, 0)].y - pixelsHigh;
for (y=0;y<pixelsHigh;y++) for (y = 0; y < pixelsHigh; y++)
{ {
for (x=0;x<pixelsWide;x++) for (x = 0; x < pixelsWide; x++)
{ {
if (x+ox<clip_x0 || x+ox>=clip_x1 || y+oy<clip_y0 || y+oy>=clip_y1) if (x + ox < clip_x0 || x + ox >= clip_x1 ||
y + oy < clip_y0 || y + oy >= clip_y1)
{ {
if (hasAlpha) if (hasAlpha)
src+=4; src += 4;
else else
src+=3; src += 3;
continue; continue;
} }
ri.dst=wi->data+(x+ox)*DI.bytes_per_pixel+(y+oy)*wi->bytes_per_line; ri.dst = wi->data + (x + ox) * DI.bytes_per_pixel
ri.dsta=wi->alpha+(x+ox)+(y+oy)*wi->sx; + (y + oy) * wi->bytes_per_line;
ri.r=src[0]; ri.dsta = wi->alpha + (x + ox) + (y + oy) * wi->sx;
ri.g=src[1]; ri.r = src[0];
ri.b=src[2]; ri.g = src[1];
ri.b = src[2];
if (hasAlpha) if (hasAlpha)
{ {
ri.a=src[3]; ri.a = src[3];
/* TODO: find out if input is premultiplied or not */ /* TODO: find out if input is premultiplied or not */
if (ri.a && ri.a!=255) /* if (ri.a && ri.a != 255)
{ {
ri.r=(255*ri.r)/ri.a; ri.r = (255 * ri.r) / ri.a;
ri.g=(255*ri.g)/ri.a; ri.g = (255 * ri.g) / ri.a;
ri.b=(255*ri.b)/ri.a; ri.b = (255 * ri.b) / ri.a;
} }*/
if (alpha_dest) if (alpha_dest)
{ {
if (src[3]==255) if (src[3] == 255)
RENDER_RUN_OPAQUE_A(&ri,1); RENDER_RUN_OPAQUE_A(&ri, 1);
else if (src[3]) else if (src[3])
RENDER_RUN_ALPHA_A(&ri,1); RENDER_RUN_ALPHA_A(&ri, 1);
} }
else else
{ {
if (src[3]==255) if (src[3] == 255)
RENDER_RUN_OPAQUE(&ri,1); RENDER_RUN_OPAQUE(&ri, 1);
else if (src[3]) else if (src[3])
RENDER_RUN_ALPHA(&ri,1); RENDER_RUN_ALPHA(&ri, 1);
} }
src+=4; src += 4;
} }
else else
{ {
ri.a=255; ri.a = 255;
if (alpha_dest) if (alpha_dest)
RENDER_RUN_OPAQUE_A(&ri,1); RENDER_RUN_OPAQUE_A(&ri, 1);
else else
RENDER_RUN_OPAQUE(&ri,1); RENDER_RUN_OPAQUE(&ri, 1);
src+=3; src += 3;
} }
} }
} }
return; return;
} }
ii.bits_per_sample=bitsPerSample; ii.bits_per_sample = bitsPerSample;
ii.bits_per_pixel=bitsPerPixel; ii.bits_per_pixel = bitsPerPixel;
ii.is_planar=isPlanar; ii.is_planar = isPlanar;
ii.has_alpha=hasAlpha; ii.has_alpha = hasAlpha;
ii.width=pixelsWide; ii.width = pixelsWide;
ii.height=pixelsHigh; ii.height = pixelsHigh;
ii.samples_per_pixel=samplesPerPixel; ii.samples_per_pixel = samplesPerPixel;
ii.bytes_per_row=bytesPerRow; ii.bytes_per_row = bytesPerRow;
ii.data=(const unsigned char **)data; ii.data = (const unsigned char **)data;
if (bitsPerSample==8 && is_rgb && if (bitsPerSample == 8 && is_rgb &&
((samplesPerPixel==3 && !hasAlpha) || ((samplesPerPixel == 3 && !hasAlpha) ||
(samplesPerPixel==4 && hasAlpha))) (samplesPerPixel == 4 && hasAlpha)))
{ {
[self _image_do_rgb_transform: &ii : matrix : _image_get_color_rgb_8]; [self _image_do_rgb_transform: &ii : matrix : _image_get_color_rgb_8];
return; return;
} }
if (is_rgb) if (is_rgb)
ii.colorspace=1; ii.colorspace = 1;
else if (colorSpaceName==NSDeviceCMYKColorSpace) else if (colorSpaceName == NSDeviceCMYKColorSpace)
ii.colorspace=2; ii.colorspace = 2;
else if (colorSpaceName==NSDeviceWhiteColorSpace || else if (colorSpaceName == NSDeviceWhiteColorSpace ||
colorSpaceName==NSDeviceBlackColorSpace || colorSpaceName == NSDeviceBlackColorSpace ||
colorSpaceName==NSCalibratedWhiteColorSpace || colorSpaceName == NSCalibratedWhiteColorSpace ||
colorSpaceName==NSCalibratedBlackColorSpace) colorSpaceName == NSCalibratedBlackColorSpace)
ii.colorspace=3; ii.colorspace = 3;
else else
ii.colorspace=0; ii.colorspace = 0;
if (ii.colorspace!=0) if (ii.colorspace != 0)
{ {
[self _image_do_rgb_transform: &ii : matrix : _image_get_color_rgb_cmyk_gray]; [self _image_do_rgb_transform: &ii : matrix :
_image_get_color_rgb_cmyk_gray];
return; return;
} }
NSLog(@"unimplemented DPSimage %ix%i |%@| bips=%i spp=%i bipp=%i bypr=%i planar=%i alpha=%i\n", NSLog(@"unimplemented DPSimage %ix%i |%@| bips=%i spp=%i bipp=%i bypr=%i planar=%i alpha=%i\n",
pixelsWide,pixelsHigh,matrix, pixelsWide, pixelsHigh, matrix,
bitsPerSample,samplesPerPixel,bitsPerPixel,bytesPerRow,isPlanar, bitsPerSample, samplesPerPixel, bitsPerPixel, bytesPerRow, isPlanar,
hasAlpha); hasAlpha);
} }