1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <png.h>
4+
5+ int bmp_to_png (const char * input_filename , const char * output_filename )
6+ {
7+ // open BMP 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+ // read BMP header
15+ unsigned char header [54 ];
16+ if (fread (header , sizeof (unsigned char ), 54 , input_file ) != 54 )
17+ {
18+ fprintf (stderr , "Error: invalid BMP file %s\n" , input_filename );
19+ fclose (input_file );
20+ return 1 ;
21+ }
22+ // check if BMP file is valid
23+ if (header [0 ] != 'B' || header [1 ] != 'M' )
24+ {
25+ fprintf (stderr , "Error: invalid BMP file %s\n" , input_filename );
26+ fclose (input_file );
27+ return 1 ;
28+ }
29+ // get image width and height from BMP header
30+ int width = * (int * )& header [18 ];
31+ int height = * (int * )& header [22 ];
32+ // calculate padding for BMP file
33+ int padding = 0 ;
34+ while ((width * 3 + padding ) % 4 != 0 )
35+ {
36+ padding ++ ;
37+ }
38+ // allocate memory for BMP image data
39+ unsigned char * bmp_data = (unsigned char * )malloc (width * height * 3 + height * padding );
40+ if (!bmp_data )
41+ {
42+ fprintf (stderr , "Error: could not allocate memory for BMP image data\n" );
43+ fclose (input_file );
44+ return 1 ;
45+ }
46+ // read BMP image data
47+ if (fread (bmp_data , sizeof (unsigned char ), width * height * 3 + height * padding , input_file ) != width * height * 3 + height * padding )
48+ {
49+ fprintf (stderr , "Error: invalid BMP file %s\n" , input_filename );
50+ free (bmp_data );
51+ fclose (input_file );
52+ return 1 ;
53+ }
54+ // close BMP file
55+ fclose (input_file );
56+ // open PNG file for writing
57+ FILE * output_file = fopen (output_filename , "wb" );
58+ if (!output_file )
59+ {
60+ fprintf (stderr , "Error: could not open output file %s\n" , output_filename );
61+ free (bmp_data );
62+ return 1 ;
63+ }
64+ // create PNG write struct
65+ png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING , NULL , NULL , NULL );
66+ if (!png_ptr )
67+ {
68+ fprintf (stderr , "Error: could not create PNG write struct\n" );
69+ free (bmp_data );
70+ fclose (output_file );
71+ return 1 ;
72+ }
73+ // create PNG info struct
74+ png_infop info_ptr = png_create_info_struct (png_ptr );
75+ if (!info_ptr )
76+ {
77+ fprintf (stderr , "Error: could not create PNG info struct\n" );
78+ free (bmp_data );
79+ png_destroy_write_struct (& png_ptr , NULL );
80+ fclose (output_file );
81+ return 1 ;
82+ }
83+ // set error handling
84+ if (setjmp (png_jmpbuf (png_ptr )))
85+ {
86+ fprintf (stderr , "Error: PNG error\n" );
87+ free (bmp_data );
88+ png_destroy_write_struct (& png_ptr , & info_ptr );
89+ fclose (output_file );
90+ return 1 ;
91+ }
92+ // set PNG output file
93+ png_init_io (png_ptr , output_file );
94+ // set PNG header info
95+ png_set_IHDR (png_ptr , info_ptr , width , height , 8 , PNG_COLOR_TYPE_RGB , PNG_INTERLACE_NONE , PNG_COMPRESSION_TYPE_DEFAULT , PNG_FILTER_TYPE_DEFAULT );
96+ // write PNG header info
97+ png_write_info (png_ptr , info_ptr );
98+ // write PNG image data
99+ for (int y = 0 ; y < height ; y ++ )
100+ {
101+ png_bytep row_pointer = & bmp_data [(height - y - 1 ) * (width * 3 + padding )];
102+ png_write_row (png_ptr , row_pointer );
103+ }
104+ // finish writing PNG file
105+ png_write_end (png_ptr , NULL );
106+ // free PNG write struct and info struct
107+ png_destroy_write_struct (& png_ptr , & info_ptr );
108+ // free BMP image data
109+ free (bmp_data );
110+ // close PNG file
111+ fclose (output_file );
112+ printf ("Converted %s to %s\n" , input_filename , output_filename );
113+
114+ return 0 ;
115+ }
0 commit comments