Skip to content

Commit ef7ff45

Browse files
committed
added bmp to jpeg converter
1 parent 708267b commit ef7ff45

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

src/converters/bmp_to_jpeg.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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

Comments
 (0)