1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <jpeglib.h>
4+
5+ int bmp_to_jpeg (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+ // allocate memory for JPEG image data
57+ unsigned char * jpeg_data = NULL ;
58+ unsigned long jpeg_size = 0 ;
59+ // create JPEG compressor object
60+ struct jpeg_compress_struct cinfo ;
61+ struct jpeg_error_mgr jerr ;
62+ cinfo .err = jpeg_std_error (& jerr );
63+ jpeg_create_compress (& cinfo );
64+ // open output file for writing
65+ FILE * output_file = fopen (output_filename , "wb" );
66+ if (!output_file )
67+ {
68+ fprintf (stderr , "Error: could not open output file %s\n" , output_filename );
69+ free (bmp_data );
70+ jpeg_destroy_compress (& cinfo );
71+ return 1 ;
72+ }
73+ // set JPEG compressor parameters
74+ cinfo .image_width = width ;
75+ cinfo .image_height = height ;
76+ cinfo .input_components = 3 ;
77+ cinfo .in_color_space = JCS_RGB ;
78+ jpeg_set_defaults (& cinfo );
79+ jpeg_set_quality (& cinfo , 75 , TRUE);
80+ // set output file for JPEG compressor
81+ jpeg_stdio_dest (& cinfo , output_file );
82+ // start JPEG compressor
83+ jpeg_start_compress (& cinfo , TRUE);
84+ // write JPEG image data
85+ while (cinfo .next_scanline < cinfo .image_height )
86+ {
87+ JSAMPROW row_pointer = & bmp_data [(cinfo .image_height - cinfo .next_scanline - 1 ) * (width * 3 + padding )];
88+ jpeg_write_scanlines (& cinfo , & row_pointer , 1 );
89+ }
90+ // finish JPEG compressor
91+ jpeg_finish_compress (& cinfo );
92+ // get size of JPEG image data
93+ jpeg_size = ftell (output_file );
94+ // close output file
95+ fclose (output_file );
96+ // destroy JPEG compressor object
97+ jpeg_destroy_compress (& cinfo );
98+ // free BMP image data
99+ free (bmp_data );
100+ printf ("Converted %s to %s (%lu bytes)\n" , input_filename , output_filename , jpeg_size );
101+
102+ return 0 ;
103+ }
0 commit comments