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 136 137
| #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); } int jpeg2rgb(unsigned char* jpeg_buffer, int jpeg_size, unsigned char* rgb_buffer, int* size, int* width, int* height) { struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; JSAMPARRAY buffer; int row_stride = 0; unsigned char* tmp_buffer = NULL; int rgb_size; if (jpeg_buffer == NULL) { printf("no jpeg buffer here.\n"); return -1; } if (rgb_buffer == NULL) { printf("you need to alloc rgb buffer.\n"); 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); return -1; } jpeg_create_decompress(&cinfo); jpeg_mem_src(&cinfo, jpeg_buffer, jpeg_size); 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; // 总大小 if (*size < rgb_size) { printf("rgb buffer to small, we need %d but has only: %d\n", rgb_size, *size); } *size = rgb_size; buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); 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); return 0; } int rgb2jpeg(unsigned char* rgb_buffer, int width, int height, int quality, unsigned char** jpeg_buffer, unsigned long* jpeg_size) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; int row_stride = 0; JSAMPROW row_pointer[1]; if (jpeg_buffer == NULL) { printf("you need a pointer for jpeg buffer.\n"); return -1; } cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_mem_dest(&cinfo, jpeg_buffer, jpeg_size); 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); return 0; }
|