1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <png.h>
4+
5+ int png_to_bmp (const char * input_filename , const char * output_filename )
6+ {
7+ // Open PNG file for reading
8+ FILE * input_file = fopen (input_filename , "rb" );
9+ if (!input_file )
10+ {
11+ fprintf (stderr , "Error: could not open input file %s\n" , input_filename );
12+ return 1 ;
13+ }
14+ // Create PNG read struct
15+ png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING , NULL , NULL , NULL );
16+ if (!png_ptr )
17+ {
18+ fprintf (stderr , "Error: could not create PNG read struct\n" );
19+ fclose (input_file );
20+ return 1 ;
21+ }
22+ // Create PNG info struct
23+ png_infop info_ptr = png_create_info_struct (png_ptr );
24+ if (!info_ptr )
25+ {
26+ fprintf (stderr , "Error: could not create PNG info struct\n" );
27+ png_destroy_read_struct (& png_ptr , NULL , NULL );
28+ fclose (input_file );
29+ return 1 ;
30+ }
31+ // Set error handling
32+ if (setjmp (png_jmpbuf (png_ptr )))
33+ {
34+ fprintf (stderr , "Error: PNG error\n" );
35+ png_destroy_read_struct (& png_ptr , & info_ptr , NULL );
36+ fclose (input_file );
37+ return 1 ;
38+ }
39+ // Initialize PNG I/O
40+ png_init_io (png_ptr , input_file );
41+ // Read PNG header info
42+ png_read_info (png_ptr , info_ptr );
43+ // Get PNG image attributes
44+ int width = png_get_image_width (png_ptr , info_ptr );
45+ int height = png_get_image_height (png_ptr , info_ptr );
46+ int color_type = png_get_color_type (png_ptr , info_ptr );
47+ int bit_depth = png_get_bit_depth (png_ptr , info_ptr );
48+ // Make sure it's a valid format for conversion
49+ if (color_type != PNG_COLOR_TYPE_RGB || bit_depth != 8 )
50+ {
51+ fprintf (stderr , "Error: unsupported PNG format\n" );
52+ png_destroy_read_struct (& png_ptr , & info_ptr , NULL );
53+ fclose (input_file );
54+ return 1 ;
55+ }
56+ // Allocate memory for PNG image data
57+ png_bytep * row_pointers = (png_bytep * )malloc (height * sizeof (png_bytep ));
58+ if (!row_pointers )
59+ {
60+ fprintf (stderr , "Error: could not allocate memory for PNG image data\n" );
61+ png_destroy_read_struct (& png_ptr , & info_ptr , NULL );
62+ fclose (input_file );
63+ return 1 ;
64+ }
65+ for (int y = 0 ; y < height ; y ++ )
66+ {
67+ row_pointers [y ] = (png_byte * )malloc (png_get_rowbytes (png_ptr , info_ptr ));
68+ if (!row_pointers [y ])
69+ {
70+ fprintf (stderr , "Error: could not allocate memory for PNG image data\n" );
71+ for (int i = 0 ; i < y ; i ++ )
72+ free (row_pointers [i ]);
73+ free (row_pointers );
74+ png_destroy_read_struct (& png_ptr , & info_ptr , NULL );
75+ fclose (input_file );
76+ return 1 ;
77+ }
78+ }
79+ // Read PNG image data
80+ png_read_image (png_ptr , row_pointers );
81+ // Close PNG file
82+ png_destroy_read_struct (& png_ptr , & info_ptr , NULL );
83+ fclose (input_file );
84+ // Open BMP file for writing
85+ FILE * output_file = fopen (output_filename , "wb" );
86+ if (!output_file )
87+ {
88+ fprintf (stderr , "Error: could not open output file %s\n" , output_filename );
89+ for (int y = 0 ; y < height ; y ++ )
90+ free (row_pointers [y ]);
91+ free (row_pointers );
92+ return 1 ;
93+ }
94+ // Write BMP header
95+ unsigned char header [54 ] = {
96+ 'B' , 'M' , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 54 , 0 , 0 , 0 , 40 , 0 ,
97+ 0 , 0 , (unsigned char )(width ), (unsigned char )(width >> 8 ), (unsigned char )(width >> 16 ), (unsigned char )(width >> 24 ),
98+ (unsigned char )(height ), (unsigned char )(height >> 8 ), (unsigned char )(height >> 16 ), (unsigned char )(height >> 24 ),
99+ 1 , 0 , 24 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
100+ fwrite (header , sizeof (unsigned char ), 54 , output_file );
101+ // Write BMP image data
102+ for (int y = height - 1 ; y >= 0 ; y -- )
103+ {
104+ for (int x = 0 ; x < width ; x ++ )
105+ {
106+ png_bytep pixel = & (row_pointers [y ][x * 3 ]);
107+ fwrite (& pixel [2 ], sizeof (png_byte ), 1 , output_file );
108+ fwrite (& pixel [1 ], sizeof (png_byte ), 1 , output_file );
109+ fwrite (& pixel [0 ], sizeof (png_byte ), 1 , output_file );
110+ }
111+ // Add padding
112+ for (int p = 0 ; p < (4 - (width * 3 ) % 4 ) % 4 ; p ++ )
113+ fputc (0 , output_file );
114+ }
115+ // Close BMP file
116+ fclose (output_file );
117+ // Free memory
118+ for (int y = 0 ; y < height ; y ++ )
119+ free (row_pointers [y ]);
120+ free (row_pointers );
121+ printf ("Converted %s to %s\n" , input_filename , output_filename );
122+ return 0 ;
123+ }
0 commit comments