simplified alpha removal and inversion in ps_embedded_image()
This commit is contained in:
parent
197379989a
commit
6405ac4c09
|
|
@ -82,7 +82,7 @@ int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y2, int
|
|||
#if defined(HAS_LIBJPEG) && HAS_CAIRO==1
|
||||
int i, jpg;
|
||||
int size_x, size_y;
|
||||
unsigned char *img_data = NULL, BG_r, BG_g, BG_b;
|
||||
unsigned char *ptr = NULL;
|
||||
int invertImage;
|
||||
unsigned char* ascii85EncodedJpeg;
|
||||
const char* attr;
|
||||
|
|
@ -129,29 +129,30 @@ int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y2, int
|
|||
cairo_paint(ct);
|
||||
cairo_destroy(ct);
|
||||
|
||||
img_data = cairo_image_surface_get_data(surface);
|
||||
ptr = cairo_image_surface_get_data(surface);
|
||||
|
||||
/* jpeg has no alpha channel so blend transparency with white */
|
||||
BG_r = 0xFF; BG_g = 0xFF; BG_b = 0xFF;
|
||||
for (i = 0; i < (size_x * size_y * 4); i += 4)
|
||||
{
|
||||
unsigned char png_r = img_data[i + 0];
|
||||
unsigned char png_g = img_data[i + 1];
|
||||
unsigned char png_b = img_data[i + 2];
|
||||
unsigned char png_a = img_data[i + 3];
|
||||
double ainv=((double)(0xFF - png_a)) / ((double)(0xFF));
|
||||
|
||||
unsigned char a = ptr[i + 3];
|
||||
unsigned char r = ptr[i + 2];
|
||||
unsigned char g = ptr[i + 1];
|
||||
unsigned char b = ptr[i + 0];
|
||||
/* invert colors */
|
||||
if(invertImage) {
|
||||
img_data[i + 0] = (unsigned char)(0xFF-png_r) + (unsigned char)((double)BG_r * ainv);
|
||||
img_data[i + 1] = (unsigned char)(0xFF-png_g) + (unsigned char)((double)BG_g * ainv);
|
||||
img_data[i + 2] = (unsigned char)(0xFF-png_b) + (unsigned char)((double)BG_b * ainv);
|
||||
img_data[i + 3] = 0xFF;
|
||||
} else {
|
||||
img_data[i + 0] = png_r + (unsigned char)((double)BG_r * ainv);
|
||||
img_data[i + 1] = png_g + (unsigned char)((double)BG_g * ainv);
|
||||
img_data[i + 2] = png_b + (unsigned char)((double)BG_b * ainv);
|
||||
img_data[i + 3] = 0xFF;
|
||||
r = a - r;
|
||||
g = a - g;
|
||||
b = a - b;
|
||||
}
|
||||
/* blend with white, remove alpha */
|
||||
r += (unsigned char)(0xff - a);
|
||||
g += (unsigned char)(0xff - a);
|
||||
b += (unsigned char)(0xff - a);
|
||||
a = (unsigned char) 0xff;
|
||||
/* write result back */
|
||||
ptr[i + 3] = a;
|
||||
ptr[i + 2] = r;
|
||||
ptr[i + 1] = g;
|
||||
ptr[i + 0] = b;
|
||||
}
|
||||
cairo_surface_mark_dirty(surface);
|
||||
if(invertImage || jpg == 0) {
|
||||
|
|
|
|||
|
|
@ -2033,13 +2033,17 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
break;
|
||||
case 'i': /*----------------------------------------------*/
|
||||
#if HAS_CAIRO==1
|
||||
/* image [invert|white_transp|black_transp|transp_white|transp_black|write_back]
|
||||
/* image [invert|white_transp|black_transp|transp_white|transp_black|write_back|
|
||||
* blend_white|blend_black]
|
||||
* Apply required changes to selected images
|
||||
* invert: invert colors
|
||||
* white_transp: transform white to transparent color (alpha=0) after invert.
|
||||
* black_transp: transform black to transparent color (alpha=0) after invert.
|
||||
* transp_white: transform white to transparent color (alpha=0) after invert.
|
||||
* transp_black: transform black to transparent color (alpha=0) after invert.
|
||||
* blend_white: blend with white background and remove alpha
|
||||
* blend_black: blend with black background and remove alpha
|
||||
* write_back: write resulting image back into `image_data` attribute
|
||||
*/
|
||||
if(!strcmp(argv[1], "image"))
|
||||
{
|
||||
|
|
@ -2053,10 +2057,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
}
|
||||
if(!strcmp(argv[2], "help")) {
|
||||
Tcl_SetResult(interp,
|
||||
"xschem image [invert|white_transp|black_transp|transp_white|transp_black|write_back]",
|
||||
"xschem image [invert|white_transp|black_transp|transp_white|transp_black|\n"
|
||||
" blend_white|blend_black|write_back]",
|
||||
TCL_STATIC);
|
||||
return TCL_OK;
|
||||
}
|
||||
if(xctx->lastsel == 0) {
|
||||
Tcl_SetResult(interp, "No images selected", TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for(i = 2; i < argc; i++) {
|
||||
if(!strcmp(argv[i], "invert")) what |= 1;
|
||||
if(!strcmp(argv[i], "white_transp")) what |= 2;
|
||||
|
|
|
|||
|
|
@ -456,9 +456,10 @@ static void svg_drawgrid()
|
|||
}
|
||||
}
|
||||
|
||||
static void svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, double ry2, int rot, int flip)
|
||||
static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, double ry2, int rot, int flip)
|
||||
{
|
||||
const char *ptr;
|
||||
const char *attr;
|
||||
size_t attr_len;
|
||||
double x1, y1, x2, y2, w, h, scalex = 1.0, scaley = 1.0;
|
||||
int jpg = 0;
|
||||
char opacity[100];
|
||||
|
|
@ -479,20 +480,29 @@ static void svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, dou
|
|||
|
||||
if(flip && (rot == 0 || rot == 2)) scalex = -1.0;
|
||||
else if(flip && (rot == 1 || rot == 3)) scaley = -1.0;
|
||||
ptr = get_tok_value(r->prop_ptr, "alpha", 0);
|
||||
if(ptr[0]) alpha = atof(ptr);
|
||||
ptr = get_tok_value(r->prop_ptr, "image_data", 0);
|
||||
attr = get_tok_value(r->prop_ptr, "alpha", 0);
|
||||
if(attr[0]) alpha = atof(attr);
|
||||
attr = get_tok_value(r->prop_ptr, "image_data", 0);
|
||||
attr_len = strlen(attr);
|
||||
|
||||
if(attr_len > 5) {
|
||||
if(!strncmp(attr, "/9j/", 4)) jpg = 1;
|
||||
else if(!strncmp(attr, "iVBOR", 5)) jpg = 0;
|
||||
else jpg = -1; /* some invalid data */
|
||||
} else {
|
||||
jpg = -1;
|
||||
}
|
||||
if(jpg == -1) {
|
||||
return 0;
|
||||
}
|
||||
my_snprintf(transform, S(transform),
|
||||
"transform=\"translate(%g,%g) scale(%g,%g) rotate(%d)\"", x1, y1, scalex, scaley, rot * 90);
|
||||
if(alpha == 1.0) strcpy(opacity, "");
|
||||
else my_snprintf(opacity, S(opacity), "style=\"opacity:%g;\"", alpha);
|
||||
if(ptr[0]) {
|
||||
if(!strncmp(ptr, "/9j/", 4)) jpg = 1; /* jpeg base64 header (24 bits checked) */
|
||||
fprintf(fd, "<image x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" %s %s "
|
||||
"xlink:href=\"data:image/%s;base64,%s\"/>\n",
|
||||
0.0, 0.0, w, h, transform, opacity, jpg ? "jpeg" : "png", ptr);
|
||||
}
|
||||
fprintf(fd, "<image x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" %s %s "
|
||||
"xlink:href=\"data:image/%s;base64,%s\"/>\n",
|
||||
0.0, 0.0, w, h, transform, opacity, jpg ? "jpeg" : "png", attr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
|
||||
|
|
|
|||
Loading…
Reference in New Issue