1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <jpeglib.h>
4+
5+ int jpeg_to_bmp (const char * input_filename , const char * output_filename )
6+ {
7+ FILE * input_file = fopen (input_filename , "rb" );
8+ if (!input_file )
9+ {
10+ fprintf (stderr , "Error: could not open input file %s\n" , input_filename );
11+ return 1 ;
12+ }
13+
14+ // Initialize JPEG decompressor object
15+ struct jpeg_decompress_struct cinfo ;
16+ struct jpeg_error_mgr jerr ;
17+ cinfo .err = jpeg_std_error (& jerr );
18+ jpeg_create_decompress (& cinfo );
19+
20+ // Specify input file for JPEG decompressor
21+ jpeg_stdio_src (& cinfo , input_file );
22+ jpeg_read_header (& cinfo , TRUE);
23+ jpeg_start_decompress (& cinfo );
24+
25+ // Get image dimensions
26+ int width = cinfo .output_width ;
27+ int height = cinfo .output_height ;
28+
29+ // Allocate memory for JPEG image data
30+ unsigned char * jpeg_data = (unsigned char * )malloc (width * height * cinfo .output_components );
31+ if (!jpeg_data )
32+ {
33+ fprintf (stderr , "Error: could not allocate memory for JPEG image data\n" );
34+ fclose (input_file );
35+ jpeg_destroy_decompress (& cinfo );
36+ return 1 ;
37+ }
38+
39+ // Read JPEG image data
40+ while (cinfo .output_scanline < cinfo .output_height )
41+ {
42+ JSAMPROW row_pointer = & jpeg_data [(cinfo .output_height - cinfo .output_scanline - 1 ) * width * cinfo .output_components ];
43+ jpeg_read_scanlines (& cinfo , & row_pointer , 1 );
44+ }
45+
46+ // Finish decompression
47+ jpeg_finish_decompress (& cinfo );
48+
49+ // Close JPEG file
50+ fclose (input_file );
51+ jpeg_destroy_decompress (& cinfo );
52+
53+ // Open output BMP file for writing
54+ FILE * output_file = fopen (output_filename , "wb" );
55+ if (!output_file )
56+ {
57+ fprintf (stderr , "Error: could not open output file %s\n" , output_filename );
58+ free (jpeg_data );
59+ return 1 ;
60+ }
61+
62+ // Write BMP header
63+ unsigned char bmp_header [54 ] = {
64+ 'B' , 'M' , // Signature
65+ 0 , 0 , 0 , 0 , // File size (to be filled later)
66+ 0 , 0 , 0 , 0 , // Reserved
67+ 54 , 0 , 0 , 0 , // Offset to pixel data
68+ 40 , 0 , 0 , 0 , // Header size
69+ 0 , 0 , 0 , 0 , // Image width (to be filled later)
70+ 0 , 0 , 0 , 0 , // Image height (to be filled later)
71+ 1 , 0 , // Number of color planes
72+ 24 , 0 , // Bits per pixel (3 bytes)
73+ 0 , 0 , 0 , 0 , // Compression method
74+ 0 , 0 , 0 , 0 , // Image size (can be 0)
75+ 0 , 0 , 0 , 0 , // Horizontal resolution (can be 0)
76+ 0 , 0 , 0 , 0 , // Vertical resolution (can be 0)
77+ 0 , 0 , 0 , 0 , // Number of colors in palette (0 for 24-bit)
78+ 0 , 0 , 0 , 0 // Number of important colors (can be 0)
79+ };
80+
81+ int bmp_file_size = sizeof (bmp_header ) + width * height * 3 ;
82+ bmp_header [2 ] = (unsigned char )(bmp_file_size );
83+ bmp_header [3 ] = (unsigned char )(bmp_file_size >> 8 );
84+ bmp_header [4 ] = (unsigned char )(bmp_file_size >> 16 );
85+ bmp_header [5 ] = (unsigned char )(bmp_file_size >> 24 );
86+ bmp_header [18 ] = (unsigned char )(width );
87+ bmp_header [19 ] = (unsigned char )(width >> 8 );
88+ bmp_header [20 ] = (unsigned char )(width >> 16 );
89+ bmp_header [21 ] = (unsigned char )(width >> 24 );
90+ bmp_header [22 ] = (unsigned char )(height );
91+ bmp_header [23 ] = (unsigned char )(height >> 8 );
92+ bmp_header [24 ] = (unsigned char )(height >> 16 );
93+ bmp_header [25 ] = (unsigned char )(height >> 24 );
94+
95+ fwrite (bmp_header , sizeof (unsigned char ), sizeof (bmp_header ), output_file );
96+
97+ // Write BMP image data
98+ for (int y = height - 1 ; y >= 0 ; y -- )
99+ {
100+ for (int x = 0 ; x < width ; x ++ )
101+ {
102+ int jpeg_index = (height - y - 1 ) * width * cinfo .output_components + x * cinfo .output_components ;
103+ fwrite (& jpeg_data [jpeg_index + 2 ], sizeof (unsigned char ), 1 , output_file ); // Blue
104+ fwrite (& jpeg_data [jpeg_index + 1 ], sizeof (unsigned char ), 1 , output_file ); // Green
105+ fwrite (& jpeg_data [jpeg_index + 0 ], sizeof (unsigned char ), 1 , output_file ); // Red
106+ }
107+
108+ // Write padding if necessary (multiple of 4 bytes)
109+ for (int p = 0 ; p < (4 - (width * 3 ) % 4 ) % 4 ; p ++ )
110+ {
111+ fputc (0 , output_file );
112+ }
113+ }
114+
115+ fclose (output_file );
116+ printf ("Converted %s to %s\n" , input_filename , output_filename );
117+
118+ return 0 ;
119+ }
0 commit comments