Ticket #1119: hbsg.c

File hbsg.c, 8.4 KB (added by aljen, 17 years ago)

needs libpng to build

Line 
1//------------------------------------------------------------------------------
2// Copyright (c) 2008, Haiku, Inc.
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21//
22// File Name: hbsg.c
23// Author: Artur Wyszynski <harakash@gmail.com>
24// Description: Haiku Boot Splash Generator
25//
26//------------------------------------------------------------------------------
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <stdarg.h>
32#include <unistd.h>
33#include <getopt.h>
34#include <png.h>
35#include "bootsplashstructs.h"
36
37bootSplashImage* splashImage = NULL;
38bootSplashIcons* splashIcons = NULL;
39bootSplashPalette* splashPalette = NULL;
40int x, y;
41int width, height;
42png_byte colorType;
43png_byte bpp;
44png_structp pngPtr;
45png_infop infoPtr;
46int noOfPasses;
47png_bytep* rowPtrs;
48FILE* finput = NULL;
49FILE* foutput = NULL;
50int verbose = 0;
51png_colorp palette;
52int paletteColors = 0;
53
54#define SAFEFREE(x) if( x ) { free( x ); x = NULL; }
55#define SAFECLOSE(x) if( x ) { fclose( x ); x = NULL; }
56
57void cleanup()
58{
59 SAFEFREE( splashImage->data )
60 SAFEFREE( splashImage )
61 SAFEFREE( splashIcons->data )
62 SAFEFREE( splashIcons )
63 SAFEFREE( splashPalette->data )
64 SAFEFREE( splashPalette )
65 SAFECLOSE( finput )
66 SAFECLOSE( foutput )
67}
68
69void printHelp()
70{
71 printf( "Usage:\n" );
72 printf( "\t--palette\tpalette\n" );
73 printf( "\t--splash\tsplash image\n" );
74 printf( "\t--icons\t\ticons image\n" );
75 printf( "\t--verbose\tverbose mode\n" );
76 printf( "Example usage:\n" );
77 printf( "\thbsg -p palette.raw -s splash.png -i icons.png\n" );
78 exit( 0 );
79}
80
81void error( const char* s, ... )
82{
83 va_list args;
84 va_start( args, s );
85 vfprintf( stderr, s, args );
86 fprintf( stderr, "\n" );
87 va_end( args );
88 cleanup();
89 exit( -1 );
90}
91
92void readPNG( char* filename )
93{
94 if( verbose )
95 printf( "Reading file %s\n", filename );
96 char header[ 8 ];
97 finput = fopen( filename, "rb" );
98 if( !finput )
99 error( "[readPNG] File %s could not be opened for reading", filename );
100
101 fread( header, 1, 8, finput );
102 if( png_sig_cmp( header, 0, 8 ) )
103 error( "[readPNG] File %s is not recognized as a PNG file", filename );
104
105 pngPtr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
106 if( !pngPtr )
107 error( "[readPNG] png_create_read_struct failed" );
108
109 infoPtr = png_create_info_struct( pngPtr );
110 if( !infoPtr )
111 error( "[readPNG] png_create_info_struct failed" );
112
113 if( setjmp( png_jmpbuf( pngPtr ) ) )
114 error( "[readPNG] Error during init_io" );
115
116 png_init_io( pngPtr, finput );
117 png_set_sig_bytes( pngPtr, 8 );
118 png_read_info( pngPtr, infoPtr );
119 width = infoPtr->width;
120 height = infoPtr->height;
121 colorType = infoPtr->color_type;
122 bpp = infoPtr->bit_depth;
123 noOfPasses = png_set_interlace_handling( pngPtr );
124 png_read_update_info( pngPtr, infoPtr );
125 if( setjmp( png_jmpbuf( pngPtr ) ) )
126 error( "[readPNG] Error during read_image" );
127
128 rowPtrs = ( png_bytep* ) malloc( sizeof( png_bytep ) * height );
129 for( y = 0; y < height; y++ )
130 {
131 rowPtrs[ y ] = ( png_byte* ) malloc( infoPtr->rowbytes );
132 }
133 png_read_image( pngPtr, rowPtrs );
134 png_get_PLTE( pngPtr, infoPtr, &palette, &paletteColors );
135 SAFECLOSE( finput )
136 verbose = 1;
137 if( verbose )
138 {
139 printf( "[PNG] width:\t%d\n", width );
140 printf( "[PNG] height:\t%d\n", height );
141 printf( "[PNG] bpp:\t%d\n", bpp );
142 printf( "[PNG] palette:\t%d\n", paletteColors );
143 }
144}
145
146void writeRAW( char* filename )
147{
148 if( verbose )
149 printf( "Writing file %s\n", filename );
150 foutput = fopen( filename, "wb" );
151 if( !foutput )
152 error( "[writeRAW] Could not open file % for writing", filename );
153
154 if( infoPtr && ( infoPtr->color_type != PNG_COLOR_TYPE_PALETTE ) && ( bpp != 4 ) )
155 error( "[writeRAW] color_type of input file must be 4 bit PALETTE not %d", infoPtr->color_type );
156
157 splashImage = ( bootSplashImage* ) malloc( sizeof( bootSplashImage ) );
158 memset( splashImage, NULL, sizeof( bootSplashImage ) );
159 splashImage->width = width;
160 splashImage->height = height;
161 splashImage->size = width * height;
162 splashImage->data = ( unsigned char* ) malloc( splashImage->size );
163 memset( splashImage->data, NULL, splashImage->size );
164 int offset = 0;
165 for( y = 0; y < height; y++ )
166 {
167 png_byte* row = rowPtrs[ y ];
168 for( x = 0; x < width; x++ )
169 {
170 png_byte* ptr = &row[ x ];
171 offset = ( y * width ) + x;
172 splashImage->data[ offset ] = ptr[ 0 ];
173 }
174 }
175 fwrite( &splashImage->width, sizeof( unsigned int ), 1, foutput );
176 fwrite( &splashImage->height, sizeof( unsigned int ), 1, foutput );
177 fwrite( &splashImage->size, sizeof( unsigned int ), 1, foutput );
178 fwrite( ( unsigned char* ) splashImage->data, splashImage->size, 1, foutput );
179 free( ( unsigned char* ) splashImage->data );
180 free( ( bootSplashImage* ) splashImage );
181 SAFECLOSE( foutput )
182}
183
184void writePalette()
185{
186 if( verbose )
187 printf( "Writing palette.raw\n" );
188 foutput = fopen( "palette.raw", "wb" );
189 if( !foutput )
190 error( "[writePalette] Could not open file palette.raw for writing" );
191
192 splashPalette = ( bootSplashPalette* ) malloc( sizeof( bootSplashPalette ) );
193 memset( splashPalette, NULL, sizeof( bootSplashPalette ) );
194 splashPalette->size = paletteColors * ( 3 * sizeof( unsigned int ) );
195 splashPalette->data = ( unsigned char* ) malloc( splashPalette->size );
196 memset( splashPalette->data, NULL, splashPalette->size );
197 int i, offset = 0;
198 for( i = 0; i < paletteColors; i++ )
199 {
200 splashPalette->data[ offset++ ] = palette[ i ].red;
201 splashPalette->data[ offset++ ] = palette[ i ].green;
202 splashPalette->data[ offset++ ] = palette[ i ].blue;
203 // printf( "palette[ %d ] = %d\t%d\t%d\n", i, palette[ i ].red, palette[ i ].green, palette[ i ].blue );
204 }
205 fwrite( &splashPalette->size, sizeof( unsigned int ), 1, foutput );
206 fwrite( ( unsigned char* ) splashPalette->data, splashPalette->size, 1, foutput );
207 free( ( unsigned char* ) splashPalette->data );
208 free( ( bootSplashPalette* ) splashPalette );
209 SAFECLOSE( foutput );
210}
211
212void parsePalette( char* filename )
213{
214
215}
216
217void parseImage( char* filename )
218{
219 int length = strlen( filename );
220 const char* rawFilename = NULL;
221 rawFilename = ( char* ) malloc( sizeof( char ) * length );
222 memset( rawFilename, NULL, sizeof( char ) * length );
223 length -= 4; // - .png
224 strncat( rawFilename, filename, length );
225 strcat( rawFilename, ".raw" );
226 if( verbose )
227 printf( "Parsing png image %s and saving as %s\n", filename, rawFilename );
228 readPNG( filename );
229 writeRAW( rawFilename );
230 writePalette();
231 SAFEFREE( rawFilename )
232}
233
234int main( int argc, char** argv )
235{
236 printf( "Haiku Boot Splash Generator\n" );
237 printf( "Copyright 2008, Artur Wyszynski <harakash@gmail.com>\n" );
238 printf( "Distributed under the terms of the Haiku License. All rights reserved.\n" );
239
240 int c;
241 static struct option longOptions[] =
242 {
243// { "verbose", 0, &verbose, 'v' },
244 { "palette", 1, 0, 'p' },
245 { "splash", 1, 0, 's' },
246 { "icons", 1, 0, 'i' },
247 { 0, 0, 0, 0 }
248 };
249
250 if(argc < 2)
251 printHelp();
252
253 while( 1 )
254 {
255 int optionIndex = 0;
256 c = getopt_long( argc, argv, "p:s:i:", longOptions, &optionIndex );
257 if( c == -1 )
258 break;
259
260 switch( c )
261 {
262 case 0:
263 {
264 if( longOptions[ optionIndex ].flag != 0 )
265 break;
266 printf( "option %s", longOptions[ optionIndex ].name );
267 if( optarg )
268 printf( " with arg %s", optarg );
269 printf( "\n" );
270 }
271 break;
272
273 case 'p':
274 {
275 parsePalette( optarg );
276 }
277 break;
278
279 case 's':
280 {
281 parseImage( optarg );
282 }
283 break;
284
285 case 'i':
286 {
287 parseImage( optarg );
288 }
289 break;
290
291// case 'v':
292// {
293// verbose = 1;
294// }
295// break;
296
297 case '?':
298 {
299 }
300 break;
301
302 default:
303 break;
304 }
305 }
306 return 0;
307}
308