Exemplo n.º 1
0
static size_t rgb2type(ss_t **out, enum ImgTypes ot, const ss_t *rgb0,
		       const struct RGB_Info *ri, const int f)
{
	ss_t *rgb_aux = NULL;
	const ss_t *rgb;
	switch (f) {	/* Apply filter, if any */
	case F_HDPCM: case F_HRDPCM: case F_HDXOR: case F_HRDXOR: case F_VDPCM:
	case F_VRDPCM: case F_VDXOR: case F_VRDXOR: case F_AVG3: case F_RAVG3:
	case F_PAETH: case F_RPAETH: case F_RSUB: case F_RRSUB: case F_GSUB:
	case F_RGSUB: case F_BSUB: case F_RBSUB:
		rgb = (f == F_HDPCM ? hrgb2dpcm : f == F_HRDPCM ? hdpcm2rgb :
		       f == F_HDXOR ? hrgb2dxor : f == F_HRDXOR ? hdxor2rgb :
		       f == F_VDPCM ? vrgb2dpcm : f == F_VRDPCM ? vdpcm2rgb :
		       f == F_VDXOR ? vrgb2dxor : f == F_VRDXOR ? vdxor2rgb :
		       f == F_AVG3 ? rgb2davg : f == F_RAVG3 ? davg2rgb :
		       f == F_PAETH ? rgb2paeth : f == F_RPAETH ? paeth2rgb :
		       f == F_RSUB ? rgb2rsub : f == F_RRSUB ? rsub2rgb :
		       f == F_GSUB ? rgb2gsub : f == F_RGSUB ? gsub2rgb :
		       f == F_BSUB ? rgb2bsub : bsub2rgb)(&rgb_aux, rgb0, ri) ?
		      rgb_aux : rgb0;
		if (rgb == rgb0)
			fprintf(stderr, "filter error! (%i)\n", f);
		break;
	default:rgb = rgb0;
		break;
	}
	size_t r = ot == IMG_tga ? rgb2tga(out, rgb, ri) :
		   ot == IMG_ppm || ot == IMG_pgm ? rgb2ppm(out, rgb, ri) :
		   IF_PNG(ot == IMG_png ? rgb2png(out, rgb, ri) :)
		   IF_JPG(ot == IMG_jpg ? rgb2jpg(out, rgb, ri) :)
		   IF_LL1(ot == IMG_ll1 ? rgb2ll1(out, rgb, ri) :)
		   ot == IMG_raw ? ss_size(ss_cpy(out, rgb)) :
		   ot == IMG_none ? rgb_info(rgb, ri) : 0;
	ss_free(&rgb_aux);
	return r;
}
Exemplo n.º 2
0
void dib_img_writer(const char *contents, FILE *out, drawingStates *states,
                    PU_BITMAPINFOHEADER BmiSrc, const unsigned char *BmpSrc,
                    size_t size, bool assign_mono_colors_from_dc) {
    char *b64Bmp = NULL;
    size_t b64s;
    char *tmp = NULL;

    // Handle simple cases first, no treatment needed for them
    switch (BmiSrc->biCompression) {
    case U_BI_JPEG:
        b64Bmp = base64_encode(BmpSrc, size, &b64s);
        fprintf(out, "xlink:href=\"data:image/jpg;base64,");
        break;
    case U_BI_PNG:
        b64Bmp = base64_encode(BmpSrc, size, &b64s);
        fprintf(out, "xlink:href=\"data:image/png;base64,");
        break;
    }
    if (b64Bmp != NULL) {
        fprintf(out, "%s\" ", b64Bmp);
        free(b64Bmp);
        return;
    }

    // more complexe treatment, with conversion to png
    RGBBitmap convert_in;
    convert_in.size = size;
    convert_in.width = BmiSrc->biWidth;
    convert_in.height = BmiSrc->biHeight;
    convert_in.pixels = (RGBPixel *)BmpSrc;
    convert_in.bytewidth = BmiSrc->biWidth * 3;
    convert_in.bytes_per_pixel = 3;

    RGBBitmap convert_out;
    convert_out.pixels = NULL;
    const U_RGBQUAD *ct = NULL;
    U_RGBQUAD monoCt[2];
    uint32_t width, height, colortype, numCt, invert;
    char *rgba_px = NULL;
    int dibparams;
    char *in;
    size_t img_size;

    RGBABitmap convert_inpng;

    // In any cases after that, we get a png blob
    fprintf(out, "xlink:href=\"data:image/png;base64,");

    switch (BmiSrc->biCompression) {
    case U_BI_RLE8:
        convert_out = rle8ToRGB8(convert_in);
        break;
    case U_BI_RLE4:
        convert_out = rle4ToRGB(convert_in);
        break;
    }

    if (convert_out.pixels != NULL) {
        in = (char *)convert_out.pixels;
        img_size = convert_out.size;
    } else {
        in = (char *)convert_in.pixels;
        img_size = convert_in.size;
    }

    dibparams =
        e2s_get_DIB_params((PU_BITMAPINFO)BmiSrc, (const U_RGBQUAD **)&ct,
                           &numCt, &width, &height, &colortype, &invert);
    // if enable to read header, then exit
    if (dibparams || width > MAX_BMP_WIDTH || height > MAX_BMP_HEIGHT) {
        free(convert_out.pixels);
        states->Error = true;
        return;
    }
    // check that what we will read in the DIB_to_RGBA conversion is actually
    // there
    size_t offset_check =
        (size_t)((float)width * (float)height * get_pixel_size(colortype));
    if (((in + img_size) < in + offset_check)) {
        free(convert_out.pixels);
        states->Error = true;
        return;
    }
    if (colortype == U_BCBM_MONOCHROME) {
        if (assign_mono_colors_from_dc) {
            monoCt[0].Red = states->currentDeviceContext.text_red;
            monoCt[0].Green = states->currentDeviceContext.text_green;
            monoCt[0].Blue = states->currentDeviceContext.text_blue;
            monoCt[0].Reserved = 0xff;
            monoCt[1].Red = states->currentDeviceContext.bk_red;
            monoCt[1].Green = states->currentDeviceContext.bk_green;
            monoCt[1].Blue = states->currentDeviceContext.bk_blue;
            monoCt[1].Reserved =
                0xff; // states->currentDeviceContext.bk_mode ? 0xff : 0;
            ct = monoCt;
        }
    }
    DIB_to_RGBA(in, ct, numCt, &rgba_px, width, height, colortype, numCt,
                invert);

    if (rgba_px != NULL) {
        convert_inpng.size = width * 4 * height;
        convert_inpng.width = width;
        convert_inpng.height = height;
        convert_inpng.pixels = (RGBAPixel *)rgba_px;
        convert_inpng.bytewidth = BmiSrc->biWidth * 3;
        convert_inpng.bytes_per_pixel = 3;

        rgb2png(&convert_inpng, &b64Bmp, &b64s);
        tmp = (char *)b64Bmp;
        b64Bmp = base64_encode((unsigned char *)b64Bmp, b64s, &b64s);
        free(convert_out.pixels);
        free(tmp);
        free(rgba_px);
    }

    if (b64Bmp != NULL) {
        fprintf(out, "%s\" ", b64Bmp);
        free(b64Bmp);
    } else {
        // transparent 5x5 px png
        fprintf(out, "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAABGdBTUEAA"
                "LGPC/xhBQAAAAZiS0dEAP8A/wD/"
                "oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+"
                "ABFREtOJX7FAkAAAAIdEVYdENvbW1lbnQA9syWvwAAAAxJREFUCNdjYKA"
                "TAAAAaQABwB3y+AAAAABJRU5ErkJggg==\" ");
    }
}