Ejemplo n.º 1
0
tree
edit_graphics_rep::graphical_select (double x, double y) { 
  frame f= find_frame ();
  if (is_nil (f)) return tuple ();
  gr_selections sels;
  point p0 = point (x, y);
  point p = f (p0);
  sels= eb->graphical_select ((SI)p[0], (SI)p[1], 10*get_pixel_size ());
  gs= sels;
  pts= array<point> (0);
  ci= array<point> (0);
  cgi= array<point> (0);
  gr0= empty_grid ();
  grid g= find_grid ();
  frame f2= find_frame (true);
  if (!is_nil (g) && !is_nil (f2)) {
    gr0= g;
    p = f2 (point (x, y));
    int i, j, n= N(sels);
    for (i=0; i<n; i++) {
      array<point> pts2= sels[i]->pts;
      if (N(pts2)>0 && norm (pts2[0] - p) <= 10*get_pixel_size ())
	pts= pts << pts2[0];
      if (N(pts2)>1 && norm (pts2[1] - p) <= 10*get_pixel_size ())
	pts= pts << pts2[1];
    }
    double eps= get_pixel_size () / 10.0;
    for (i=0; i<n; i++) {
      for (j=0; j<n; j++)
        if (i<j) {
	  curve c1= sels[i]->c;
	  curve c2= sels[j]->c;
	  if (!is_nil (c1) && !is_nil (c2))
	    ci= ci << intersection (c1, c2, p, eps);
        }
    }
    array<grid_curve> gc= g->get_curves_around (p0, 10*get_pixel_size (), f);
    //FIXME: Too slow
    for (i=0; i<N(gc); i++) {
      curve c= f2 (gc[i]->c);
      for (j=0; j<n; j++)
	if (!is_nil (sels[j]->c))
	  cgi= cgi << intersection (c, sels[j]->c, p, eps);
    }
  }
  return as_tree (sels);
}
Ejemplo n.º 2
0
Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const {
	if (triangle_mesh.is_valid())
		return triangle_mesh;

	PoolVector<Vector3> faces;
	faces.resize(6);
	PoolVector<Vector3>::Write facesw = faces.write();

	Rect2 final_rect = get_item_rect();

	if (final_rect.size.x == 0 || final_rect.size.y == 0)
		return Ref<TriangleMesh>();

	float pixel_size = get_pixel_size();

	Vector2 vertices[4] = {

		(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
		(final_rect.position + final_rect.size) * pixel_size,
		(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
		final_rect.position * pixel_size,

	};

	int x_axis = ((axis + 1) % 3);
	int y_axis = ((axis + 2) % 3);

	if (axis != Vector3::AXIS_Z) {
		SWAP(x_axis, y_axis);

		for (int i = 0; i < 4; i++) {
			if (axis == Vector3::AXIS_Y) {
				vertices[i].y = -vertices[i].y;
			} else if (axis == Vector3::AXIS_X) {
				vertices[i].x = -vertices[i].x;
			}
		}
	}

	static const int indices[6] = {
		0, 1, 2,
		0, 2, 3
	};

	for (int j = 0; j < 6; j++) {
		int i = indices[j];
		Vector3 vtx;
		vtx[x_axis] = vertices[i][0];
		vtx[y_axis] = vertices[i][1];
		facesw[j] = vtx;
	}

	facesw = PoolVector<Vector3>::Write();

	triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh));
	triangle_mesh->create(faces);

	return triangle_mesh;
}
Ejemplo n.º 3
0
point
edit_graphics_rep::adjust (point p) {
  frame f= find_frame ();
  grid g= find_grid ();
  if (!is_nil (g) && !is_nil (gr0) &&
      (g != gr0 || p[0] != p_x || p[1] != p_y)) {
    graphical_select (p[0], p[1]);
    g= gr0;
    p[0]= p_x;
    p[1]= p_y;
  }
  if (is_nil (g)) return p;
  point res;
  gr_selections sels= copy (gs);
  frame f2= find_frame (true);
  if (is_nil (f2)) return p;
  point fp= f2 (p);
  if ((tree) g != "empty_grid") {
    point q= g->find_point_around (p, snap_distance, f);
    point fq= f2 (q);
    if (norm (fq - fp) < snap_distance) {
      gr_selection sel;
      sel->type= "grid-point";
      sel->p   = fq;
      sel->dist= (SI) norm (fq - fp);
      sels << sel;
    }
    array<grid_curve> gc=
      g->get_curves_around (p, snap_distance, f);
    for (int i=0; i<N(gc); i++) {
      point fc= closest (f2 (gc[i]->c), fp);
      if (norm (fc - fp) < snap_distance) {
        gr_selection sel;
        sel->type= "grid-curve-point";
        sel->p   = fc;
        sel->dist= (SI) norm (fc - fp);
        sel->c   = f2 (gc[i]->c);
        sels << sel;
      }
    }
  }
  double eps= get_pixel_size () / 10.0;
  gr_selection snap= snap_to_guide (fp, sels, eps);
  //cout << "Snap " << fp << " to " << snap << ", " << snap->p << "\n";
  point snapped= f2[snap->p];
  if (N(snapped) == 2) return snapped;
  return p;
  // FIXME: why can snapped be an invalid point?
}
Ejemplo n.º 4
0
int Graph_Create( LCUI_Graph *graph, int w, int h )
{
	size_t size;
	if( w > 10000 || h > 10000 ) {
		_DEBUG_MSG("graph size is too large!");
		abort();
	}
	if( h <= 0 || w <= 0 ) {
		Graph_Free( graph );
		return -1;
	}
	graph->bytes_per_pixel = get_pixel_size( graph->color_type );
	graph->bytes_per_row = graph->bytes_per_pixel * w;
	size = graph->bytes_per_row * h;
	if( Graph_IsValid(graph) ) {
		/* 如果现有图形尺寸大于要创建的图形的尺寸,直接改尺寸即可 */
		if( graph->mem_size >= size ) {
			if( (w != graph->w || h != graph->h)
			 && graph->color_type == COLOR_TYPE_ARGB ) {
				Graph_FillAlpha( graph, 0 );
				Graph_FillColor(graph, RGB(255,255,255));
			}
			graph->w = w;
			graph->h = h;
			return 0;
		}
		Graph_Free( graph );
	}
	graph->mem_size = size;
	graph->bytes = (uchar_t*)malloc( size );
	if( !graph->bytes ) {
		graph->w = 0;
		graph->h = 0;
		return -2;
	}
	/* 默认全透明 */
	if( graph->color_type == COLOR_TYPE_ARGB ) {
		Graph_FillAlpha( graph, 0 );
	}
	graph->w = w;
	graph->h = h;
	return 0;
}
Ejemplo n.º 5
0
void AnimatedSprite3D::_draw() {

	RID immediate = get_immediate();
	VS::get_singleton()->immediate_clear(immediate);

	if (!frames.is_valid() || !frames->get_frame_count(animation) || frame<0 || frame>=frames->get_frame_count(animation)) {
		return;
	}

	Ref<Texture> texture = frames->get_frame(animation,frame);
	if (!texture.is_valid())
		return; //no texuture no life
	Vector2 tsize = texture->get_size();
	if (tsize.x==0 || tsize.y==0)
		return;

	Size2i s=tsize;
	Rect2i src_rect;

	src_rect.size=s;

	Point2i ofs=get_offset();
	if (is_centered())
		ofs-=s/2;

	Rect2i dst_rect(ofs,s);


	Rect2 final_rect;
	Rect2 final_src_rect;
	if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect))
		return;


	if (final_rect.size.x==0 || final_rect.size.y==0)
		return;

	Color color=_get_color_accum();
	color.a*=get_opacity();

	float pixel_size=get_pixel_size();

	Vector2 vertices[4]={

		(final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size,
		(final_rect.pos+final_rect.size) * pixel_size,
		(final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size,
		final_rect.pos * pixel_size,


	};
	Vector2 uvs[4]={
		final_src_rect.pos / tsize,
		(final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize,
		(final_src_rect.pos+final_src_rect.size) / tsize,
		(final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize,
	};

	if (is_flipped_h()) {
		SWAP(uvs[0],uvs[1]);
		SWAP(uvs[2],uvs[3]);
	}
	if (is_flipped_v()) {

		SWAP(uvs[0],uvs[3]);
		SWAP(uvs[1],uvs[2]);
	}


	Vector3 normal;
	int axis = get_axis();
	normal[axis]=1.0;

	RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS);
	VS::get_singleton()->immediate_set_material(immediate,mat);

	VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid());

	int x_axis = ((axis + 1) % 3);
	int y_axis = ((axis + 2) % 3);

	if (axis!=Vector3::AXIS_Z) {
		SWAP(x_axis,y_axis);

		for(int i=0;i<4;i++) {
			//uvs[i] = Vector2(1.0,1.0)-uvs[i];
			//SWAP(vertices[i].x,vertices[i].y);
			if (axis==Vector3::AXIS_Y) {
				vertices[i].y = - vertices[i].y;
			} else if (axis==Vector3::AXIS_X) {
				vertices[i].x = - vertices[i].x;
			}
		}
	}

	AABB aabb;

	for(int i=0;i<4;i++) {
		VS::get_singleton()->immediate_normal(immediate,normal);
		VS::get_singleton()->immediate_color(immediate,color);
		VS::get_singleton()->immediate_uv(immediate,uvs[i]);

		Vector3 vtx;
		vtx[x_axis]=vertices[i][0];
		vtx[y_axis]=vertices[i][1];
		VS::get_singleton()->immediate_vertex(immediate,vtx);
		if (i==0) {
			aabb.pos=vtx;
			aabb.size=Vector3();
		} else {
			aabb.expand_to(vtx);
		}
	}
	set_aabb(aabb);
	VS::get_singleton()->immediate_end(immediate);

}
Ejemplo n.º 6
0
void Sprite3D::_draw() {

	RID immediate = get_immediate();

	VS::get_singleton()->immediate_clear(immediate);
	if (!texture.is_valid())
		return; //no texuture no life
	Vector2 tsize = texture->get_size();
	if (tsize.x==0 || tsize.y==0)
		return;

	Size2i s;
	Rect2i src_rect;

	if (region) {

		s=region_rect.size;
		src_rect=region_rect;
	} else {
		s = texture->get_size();
		s=s/Size2i(hframes,vframes);

		src_rect.size=s;
		src_rect.pos.x+=(frame%hframes)*s.x;
		src_rect.pos.y+=(frame/hframes)*s.y;

	}

	Point2i ofs=get_offset();
	if (is_centered())
		ofs-=s/2;

	Rect2i dst_rect(ofs,s);


	Rect2 final_rect;
	Rect2 final_src_rect;
	if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect))
		return;


	if (final_rect.size.x==0 || final_rect.size.y==0)
		return;

	Color color=_get_color_accum();
	color.a*=get_opacity();

	float pixel_size=get_pixel_size();

	Vector2 vertices[4]={

		(final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size,
		(final_rect.pos+final_rect.size) * pixel_size,
		(final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size,
		final_rect.pos * pixel_size,


	};
	Vector2 uvs[4]={
		final_src_rect.pos / tsize,
		(final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize,
		(final_src_rect.pos+final_src_rect.size) / tsize,
		(final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize,
	};

	if (is_flipped_h()) {
		SWAP(uvs[0],uvs[1]);
		SWAP(uvs[2],uvs[3]);
	}
	if (is_flipped_v()) {

		SWAP(uvs[0],uvs[3]);
		SWAP(uvs[1],uvs[2]);
	}


	Vector3 normal;
	int axis = get_axis();
	normal[axis]=1.0;

	RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS);
	VS::get_singleton()->immediate_set_material(immediate,mat);

	VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid());

	int x_axis = ((axis + 1) % 3);
	int y_axis = ((axis + 2) % 3);

	AABB aabb;

	for(int i=0;i<4;i++) {
		VS::get_singleton()->immediate_normal(immediate,normal);
		VS::get_singleton()->immediate_color(immediate,color);
		VS::get_singleton()->immediate_uv(immediate,uvs[i]);

		Vector3 vtx;
		vtx[x_axis]=vertices[i][x_axis];
		vtx[y_axis]=vertices[i][y_axis];
		VS::get_singleton()->immediate_vertex(immediate,vtx);
		if (i==0) {
			aabb.pos=vtx;
			aabb.size=Vector3();
		} else {
			aabb.expand_to(vtx);
		}
	}
	set_aabb(aabb);
	VS::get_singleton()->immediate_end(immediate);


}
Ejemplo n.º 7
0
point
edit_graphics_rep::adjust (point p) {
  frame f= find_frame ();
  grid g= find_grid ();
  if (!is_nil (g) && !is_nil (gr0) && g!=gr0) {
    graphical_select (p[0], p[1]);
    g= gr0;
  }
  if (is_nil (g))
    return p;
  else {
    point res;
    gr_selections sels= gs;
    frame f2= find_frame (true);
    if (!is_nil (f2)) {
      point fp= f2 (p);
      int i;
      if ((tree)g == "empty_grid") {
	if (N(pts)>0)
	  res= pts[0];
	for (i=0; i<N(pts); i++) {
	  point sp= pts[i];
	  if (N(sp)>0 && norm (fp - sp) < 5*get_pixel_size ())
	    res= pts[i];
	}
	int n= N(sels);
	for (i=0; i<n; i++) {
	  point sp= sels[i]->p;
	  if (N(res)==0 || (N(sp)>0 && norm (fp - sp) < 5*get_pixel_size ()
			            && norm (fp - sp) < norm (fp - res)))
	    res= sels[i]->p;
	}
      }
      else
      if (!is_nil (f)) { 
	res= f2 (g->find_point_around (p, 10*get_pixel_size (), f));
	for (i=0; i<N(pts); i++) {
	  point sp= pts[i];
	  if (N(sp)>0 && norm (fp - sp) < norm (fp - res))
	    res= pts[i];
	}
	for (i=0; i<N(ci); i++) {
	  point sp= ci[i];
	  if (N(sp)>0 && norm (fp - sp) < norm (fp - res))
	    res= ci[i];
	}
	for (i=0; i<N(cgi); i++) {
	  point sp= cgi[i];
	  if (N(sp)>0 && norm (fp - sp) < norm (fp - res))
	    res= cgi[i];
	}
      //TODO: Adjusting by means on freely moving on surface of closed curves
	;
      }
      if (N(res)>0)
	res= f2[res];
      else
	res= p;
    }
    return res;
  }
}
Ejemplo n.º 8
0
void Sprite3D::_draw() {

	RID immediate = get_immediate();

	VS::get_singleton()->immediate_clear(immediate);
	if (!texture.is_valid())
		return; //no texuture no life
	Vector2 tsize = texture->get_size();
	if (tsize.x == 0 || tsize.y == 0)
		return;

	Size2i s;
	Rect2i src_rect;

	if (region) {

		s = region_rect.size;
		src_rect = region_rect;
	} else {
		s = texture->get_size();
		s = s / Size2i(hframes, vframes);

		src_rect.size = s;
		src_rect.position.x += (frame % hframes) * s.x;
		src_rect.position.y += (frame / hframes) * s.y;
	}

	Point2i ofs = get_offset();
	if (is_centered())
		ofs -= s / 2;

	Rect2i dst_rect(ofs, s);

	Rect2 final_rect;
	Rect2 final_src_rect;
	if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect))
		return;

	if (final_rect.size.x == 0 || final_rect.size.y == 0)
		return;

	Color color = _get_color_accum();
	color.a *= get_opacity();

	float pixel_size = get_pixel_size();

	Vector2 vertices[4] = {

		(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
		(final_rect.position + final_rect.size) * pixel_size,
		(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
		final_rect.position * pixel_size,

	};

	Vector2 src_tsize = tsize;

	// Properly setup UVs for impostor textures (AtlasTexture).
	Ref<AtlasTexture> atlas_tex = texture;
	if (atlas_tex != NULL) {
		src_tsize[0] = atlas_tex->get_atlas()->get_width();
		src_tsize[1] = atlas_tex->get_atlas()->get_height();
	}

	Vector2 uvs[4] = {
		final_src_rect.position / src_tsize,
		(final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / src_tsize,
		(final_src_rect.position + final_src_rect.size) / src_tsize,
		(final_src_rect.position + Vector2(0, final_src_rect.size.y)) / src_tsize,
	};

	if (is_flipped_h()) {
		SWAP(uvs[0], uvs[1]);
		SWAP(uvs[2], uvs[3]);
	}
	if (is_flipped_v()) {

		SWAP(uvs[0], uvs[3]);
		SWAP(uvs[1], uvs[2]);
	}

	Vector3 normal;
	int axis = get_axis();
	normal[axis] = 1.0;

	RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS);
	VS::get_singleton()->immediate_set_material(immediate, mat);

	VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid());

	int x_axis = ((axis + 1) % 3);
	int y_axis = ((axis + 2) % 3);

	if (axis != Vector3::AXIS_Z) {
		SWAP(x_axis, y_axis);

		for (int i = 0; i < 4; i++) {
			//uvs[i] = Vector2(1.0,1.0)-uvs[i];
			//SWAP(vertices[i].x,vertices[i].y);
			if (axis == Vector3::AXIS_Y) {
				vertices[i].y = -vertices[i].y;
			} else if (axis == Vector3::AXIS_X) {
				vertices[i].x = -vertices[i].x;
			}
		}
	}

	AABB aabb;

	for (int i = 0; i < 4; i++) {
		VS::get_singleton()->immediate_normal(immediate, normal);
		VS::get_singleton()->immediate_color(immediate, color);
		VS::get_singleton()->immediate_uv(immediate, uvs[i]);

		Vector3 vtx;
		vtx[x_axis] = vertices[i][0];
		vtx[y_axis] = vertices[i][1];
		VS::get_singleton()->immediate_vertex(immediate, vtx);
		if (i == 0) {
			aabb.position = vtx;
			aabb.size = Vector3();
		} else {
			aabb.expand_to(vtx);
		}
	}
	set_aabb(aabb);
	VS::get_singleton()->immediate_end(immediate);
}
Ejemplo n.º 9
0
			/**
			 * The size of a compressed block.
			 * @return Size of a compressed block (4x4) in bytes.
			 */
			inline Uint16 get_block_size() const
			{
				return get_block_size(get_pixel_size());
			}
Ejemplo n.º 10
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==\" ");
    }
}