1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <setjmp.h> #include <math.h> #include <sys/time.h> #include <time.h> // jpeg库头文件必须放到stdio.h后面 #include "libjpeg/include/jpeglib.h" #include "libjpeg/include/jerror.h" typedef struct my_error_mgr * my_error_ptr; void my_error_exit (j_common_ptr cinfo) { my_error_ptr myerr = (my_error_ptr) cinfo->err; (*cinfo->err->output_message) (cinfo); longjmp(myerr->setjmp_buffer, 1); } // 读取JPG图片数据,并解压到内存中,*rgb_buffer需要自行释放 int read_jpeg_file(const char* jpeg_file, unsigned char** rgb_buffer, int* size, int* width, int* height) { struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; FILE* fp; JSAMPARRAY buffer; int row_stride = 0; unsigned char* tmp_buffer = NULL; int rgb_size; fp = fopen(jpeg_file, "rb"); if (fp == NULL) { printf("open file %s failed.\n", jpeg_file); return -1; } cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); fclose(fp); return -1; } jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, fp); jpeg_read_header(&cinfo, TRUE); //cinfo.out_color_space = JCS_RGB; //JCS_YCbCr; // 设置输出格式 jpeg_start_decompress(&cinfo); row_stride = cinfo.output_width * cinfo.output_components; *width = cinfo.output_width; *height = cinfo.output_height; rgb_size = row_stride * cinfo.output_height; // 总大小 *size = rgb_size; buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); *rgb_buffer = (unsigned char *)malloc(sizeof(char) * rgb_size); // 分配总内存 printf("debug--:\nrgb_size: %d, size: %d w: %d h: %d row_stride: %d \n", rgb_size, cinfo.image_width*cinfo.image_height*3, cinfo.image_width, cinfo.image_height, row_stride); tmp_buffer = *rgb_buffer; while (cinfo.output_scanline < cinfo.output_height) // 解压每一行 { jpeg_read_scanlines(&cinfo, buffer, 1); // 复制到内存 memcpy(tmp_buffer, buffer[0], row_stride); tmp_buffer += row_stride; } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose(fp); return 0; } int write_jpeg_file(const char* jpeg_file, unsigned char* rgb_buffer, int width, int height, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; int row_stride = 0; FILE* fp = NULL; JSAMPROW row_pointer[1]; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); fp = fopen(jpeg_file, "wb"); if (fp == NULL) { printf("open file %s failed.\n", jpeg_file); return -1; } jpeg_stdio_dest(&cinfo, fp); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, 1); // todo 1 == true jpeg_start_compress(&cinfo, TRUE); row_stride = width * cinfo.input_components; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = &rgb_buffer[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); fclose(fp); return 0; }
|