regedit: Use a helper function to allocate memory and check for a valid pointer.
[wine.git] / tools / buildimage
blobfd6661e4f4102ffc0d9575f6de1dd93b6d01d841
1 #! /usr/bin/perl -w
3 # Render SVG files containing one or more images into an ICO or BMP.
5 # Copyright (C) 2010 Joel Holdsworth
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # Lesser General Public License for more details.
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 use strict;
22 use warnings;
23 use XML::Parser;
24 use MIME::Base64;
25 use File::Copy;
27 # Parse the parameters
28 my $svgFileName = $ARGV[0];
29 my $outFileName = $ARGV[1];
31 die "Cannot open SVG file" unless defined($svgFileName);
32 die "Cannot open output file" unless defined($outFileName);
34 $outFileName =~ m/(.*)\.(.*)/;
35 my $outName = $1;
36 my $ext = lc($2);
37 die "Only BMP, ICO and CUR outputs are supported" unless $ext eq "bmp" or $ext eq "ico" or $ext eq "cur";
39 my $renderedSVGFileName = "$svgFileName.png";
40 my @pngFiles;
42 # Get the programs from the environment variables
43 my $convert = $ENV{"CONVERT"} || "convert";
44 my $rsvg = $ENV{"RSVG"} || "rsvg";
45 my @icotool_args = ($ENV{"ICOTOOL"} || "icotool", "--create",
46 $ext eq "cur" ? "--cursor" : "--icon", "-o", $outFileName);
48 # Be ready to abort
49 sub cleanup()
51 unlink $renderedSVGFileName;
52 unlink $_ foreach(@pngFiles);
55 $SIG{"INT"} = "cleanup";
56 $SIG{"HUP"} = "cleanup";
57 $SIG{"TERM"} = "cleanup";
58 $SIG{"__DIE__"} = "cleanup";
60 # run a shell command and die on error
61 sub shell(@)
63 my @args = @_;
64 system(@args) == 0 or die "@args failed: $?";
67 sub svg_element_start
69 my($expat, $element, %attr) = @_;
71 # Parse the id for icon/bitmap render directives
72 my $id = $attr{'id'};
73 return unless defined($id);
75 my $size = 0;
76 my $depth = 0;
77 my $width = 0;
78 my $height = 0;
80 if ($id eq "hotspot")
82 push @icotool_args, "--hotspot-x=$attr{x}", "--hotspot-y=$attr{y}";
83 return;
86 if($ext eq "ico") {
87 return unless $id =~ /icon:(\d*)-(\d*)/;
88 $size = $1;
89 $depth = $2;
90 } elsif($ext eq "cur") {
91 return unless $id =~ /cursor:(\d*)-(\d*)/;
92 $size = $1;
93 $depth = $2;
94 } elsif($ext eq "bmp") {
95 return unless $id =~ /bitmap:(\d*)-(\d*)/;
96 $size = $1;
97 $depth = $2;
100 return unless defined($size) and defined($depth);
102 warn "Unexpected depth" unless
103 $depth == 1 or $depth == 4 or $depth == 8 or $depth == 24 or $depth == 32;
104 my $pngFileName = "$outName-$size-$depth.png";
106 if($element eq "svg") {
108 if ($ext eq "bmp") {
109 if ($depth == 24) {
110 shell $convert, $renderedSVGFileName, "+matte", $outFileName;
111 } else {
112 shell $convert, $renderedSVGFileName, $outFileName;
114 cleanup();
115 exit(0);
118 # The whole file is tagged
119 $pngFileName = $renderedSVGFileName;
121 } elsif($element eq "rect") {
123 # Extract SVG vector images
124 my $x = $attr{'x'};
125 my $y = $attr{'y'};
126 $width = $attr{'width'};
127 $height = $attr{'height'};
129 if(defined($x) and defined($y)) {
130 if($x =~ /\d*/ and $y =~ /\d*/) {
131 shell $convert, $renderedSVGFileName, "-crop", "${width}x${height}+$x+$y", "-depth", $depth, $pngFileName;
134 } elsif($element eq "image" ) {
136 # Extract Base64 encoded PNG data to files
137 my $xlinkHref = $attr{'xlink:href'};
138 if(defined($xlinkHref)) {
139 $xlinkHref =~ /data:image\/png;base64(.*)/;
140 my $imageEncodedData = $1;
141 if(defined $imageEncodedData) {
142 open(FILE, '>' . $pngFileName) or die "$!";
143 print FILE decode_base64($imageEncodedData);
144 close FILE;
147 } else {
148 return;
151 if ($width >= 128 && $height >= 128)
153 push @icotool_args, "--raw=$pngFileName";
155 else
157 push @icotool_args, $pngFileName;
159 push @pngFiles, $pngFileName;
162 # Render the SVG image
163 my @rsvgCmd;
164 push(@rsvgCmd, $rsvg);
165 push(@rsvgCmd, $svgFileName);
166 push(@rsvgCmd, "-o") if ($rsvg eq "rsvg-convert");
167 push(@rsvgCmd, $renderedSVGFileName);
168 shell @rsvgCmd;
170 # Render the images in the SVG
171 my $parser = new XML::Parser(
172 Handlers => {Start => \&svg_element_start});
173 $parser->parsefile("$svgFileName");
175 die "no render directive found in $svgFileName" unless @pngFiles;
177 shell @icotool_args;
179 # Delete the intermediate images
180 cleanup();