1 #include <stdio.h> // jpeglib需要FILE和size_t的定义
2 #include <windows.h>
3 #include "debug.h"
4 #include "jpeglib.h"
5 #pragma comment(lib, "libjpeg.lib")
6
7 extern HBITMAP jpg2bmp(unsigned char *jpg_buffer, unsigned jpg_size)
8 {
9 int rc;
10 struct jpeg_decompress_struct cinfo;
11 struct jpeg_error_mgr jerr;
12 BITMAPINFO bi; // = {};
13 LPBYTE lpBuf, pb = NULL;
14 HBITMAP hbm;
15 JSAMPARRAY buffer; // {};
16 INT row = 0;
17
18 DEBUG_PUTS("读取jpg");
19
20 cinfo.err = jpeg_std_error(&jerr);
21 jpeg_create_decompress(&cinfo);
22
23 jpeg_mem_src(&cinfo, jpg_buffer, jpg_size);
24
25 rc = jpeg_read_header(&cinfo, TRUE); // read jpeg file header
26
27 if (rc != 1) {
28 // File does not seem to be a normal JPEG
29 return NULL;
30 }
31
32 jpeg_start_decompress(&cinfo); // decompress the file
33
34 row = ((cinfo.output_width * 3 + 3) & ~3);
35 buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE,
36 row, 1);
37
38 ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
39 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
40 bi.bmiHeader.biWidth = cinfo.output_width;
41 bi.bmiHeader.biHeight = cinfo.output_height;
42 bi.bmiHeader.biPlanes = 1;
43 bi.bmiHeader.biBitCount = 24;
44 bi.bmiHeader.biCompression = BI_RGB;
45 bi.bmiHeader.biSizeImage = row * cinfo.output_height;
46
47 hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&lpBuf, NULL, 0);
48
49 if (hbm == NULL)
50 {
51 DEBUG_PUTS("hbm NULL");
52 jpeg_destroy_decompress(&cinfo);
53 return NULL;
54 }
55
56 DEBUG_PUTS("hbm正常");
57
58 pb = lpBuf + row * cinfo.output_height;
59 DEBUG_PRINTF("行 %d 输出高度 %d\n", row, cinfo.output_height);
60 while (cinfo.output_scanline < cinfo.output_height)
61 {
62 pb -= row;
63 jpeg_read_scanlines(&cinfo, buffer, 1);
64
65 if (cinfo.out_color_components == 1)
66 {
67 UINT i;
68 LPBYTE p = (LPBYTE)buffer[0];
69
70 for (i = 0; i < cinfo.output_width; i++)
71 pb[3 * i + 0] = pb[3 * i + 1] = pb[3 * i + 2] = p[i];
72 }
73 else if (cinfo.out_color_components == 3)
74 {
75 // There was talk on Internet about one being RGB and another BGR.
76 // If colors appear swapped, then swap the bytes, and update this comment.
77 // CopyMemory(pb, buffer[0], row);
78
79 // Updated color correction
80 UINT i;
81 LPBYTE p = (LPBYTE)buffer[0];
82
83 for (i = 0; i < row; i += 3)
84 {
85 pb[i + 0] = p[i + 2]; // Blue
86 pb[i + 1] = p[i + 1]; // Green
87 pb[i + 2] = p[i + 0]; // Red
88 }
89 }
90 else
91 {
92 DEBUG_PUTS("【异常】cinfo.out_color_components无效");
93 jpeg_destroy_decompress(&cinfo);
94 DeleteObject(hbm);
95 return NULL;
96 }
97 }
98
99 DEBUG_PUTS("即将调用SetDIBits");
100
101 SetDIBits(NULL, hbm, 0, cinfo.output_height, lpBuf, &bi, DIB_RGB_COLORS);
102
103 jpeg_finish_decompress(&cinfo);
104 jpeg_destroy_decompress(&cinfo);
105
106 return hbm;
107 }