1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <jpeglib.h>
4+
5+ int bmp_to_jpeg (int argc , char * argv [])
6+ {
7+ if (argc != 3 )
8+ {
9+ fprintf (stderr , "Usage: %s input.bmp output.jpg\n" , argv [0 ]);
10+ return 1 ;
11+ }
12+
13+ char * input_filename = argv [1 ];
14+ char * output_filename = argv [2 ];
15+
16+ // open BMP file for reading
17+ FILE * input_file = fopen (input_filename , "rb" );
18+ if (!input_file )
19+ {
20+ fprintf (stderr , "Error: could not open input file %s\n" , input_filename );
21+ return 1 ;
22+ }
23+ // read BMP header
24+ unsigned char header [54 ];
25+ if (fread (header , sizeof (unsigned char ), 54 , input_file ) != 54 )
26+ {
27+ fprintf (stderr , "Error: invalid BMP file %s\n" , input_filename );
28+ fclose (input_file );
29+ return 1 ;
30+ }
31+ // check if BMP file is valid
32+ if (header [0 ] != 'B' || header [1 ] != 'M' )
33+ {
34+ fprintf (stderr , "Error: invalid BMP file %s\n" , input_filename );
35+ fclose (input_file );
36+ return 1 ;
37+ }
38+ // get image width and height from BMP header
39+ int width = * (int * )& header [18 ];
40+ int height = * (int * )& header [22 ];
41+ // calculate padding for BMP file
42+ int padding = 0 ;
43+ while ((width * 3 + padding ) % 4 != 0 )
44+ {
45+ padding ++ ;
46+ }
47+ // allocate memory for BMP image data
48+ unsigned char * bmp_data = (unsigned char * )malloc (width * height * 3 + height * padding );
49+ if (!bmp_data )
50+ {
51+ fprintf (stderr , "Error: could not allocate memory for BMP image data\n" );
52+ fclose (input_file );
53+ return 1 ;
54+ }
55+ // read BMP image data
56+ if (fread (bmp_data , sizeof (unsigned char ), width * height * 3 + height * padding , input_file ) != width * height * 3 + height * padding )
57+ {
58+ fprintf (stderr , "Error: invalid BMP file %s\n" , input_filename );
59+ free (bmp_data );
60+ fclose (input_file );
61+ return 1 ;
62+ }
63+ // close BMP file
64+ fclose (input_file );
65+ // allocate memory for JPEG image data
66+ unsigned char * jpeg_data = NULL ;
67+ unsigned long jpeg_size = 0 ;
68+ // create JPEG compressor object
69+ struct jpeg_compress_struct cinfo ;
70+ struct jpeg_error_mgr jerr ;
71+ cinfo .err = jpeg_std_error (& jerr );
72+ jpeg_create_compress (& cinfo );
73+ // open output file for writing
74+ FILE * output_file = fopen (output_filename , "wb" );
75+ if (!output_file )
76+ {
77+ fprintf (stderr , "Error: could not open output file %s\n" , output_filename );
78+ free (bmp_data );
79+ jpeg_destroy_compress (& cinfo );
80+ return 1 ;
81+ }
82+ // set JPEG compressor parameters
83+ cinfo .image_width = width ;
84+ cinfo .image_height = height ;
85+ cinfo .input_components = 3 ;
86+ cinfo .in_color_space = JCS_RGB ;
87+ jpeg_set_defaults (& cinfo );
88+ jpeg_set_quality (& cinfo , 75 , TRUE);
89+ // set output file for JPEG compressor
90+ jpeg_stdio_dest (& cinfo , output_file );
91+ // start JPEG compressor
92+ jpeg_start_compress (& cinfo , TRUE);
93+ // write JPEG image data
94+ while (cinfo .next_scanline < cinfo .image_height )
95+ {
96+ JSAMPROW row_pointer = & bmp_data [(cinfo .image_height - cinfo .next_scanline - 1 ) * (width * 3 + padding )];
97+ jpeg_write_scanlines (& cinfo , & row_pointer , 1 );
98+ }
99+ // finish JPEG compressor
100+ jpeg_finish_compress (& cinfo );
101+ // get size of JPEG image data
102+ jpeg_size = ftell (output_file );
103+ // close output file
104+ fclose (output_file );
105+ // destroy JPEG compressor object
106+ jpeg_destroy_compress (& cinfo );
107+ // free BMP image data
108+ free (bmp_data );
109+ printf ("Converted %s to %s (%lu bytes)\n" , input_filename , output_filename , jpeg_size );
110+
111+ return 0 ;
112+ }
0 commit comments