📄 picture.c
字号:
/* picture.c * * Various funtions for saving/loading pictures. * Copyright 2002 by Jeroen Vreeken (pe1rxq@amsat.org) * Portions of this file are Copyright by Lionnel Maugis * This software is distributed under the GNU public license version 2 * See also the file 'COPYING'. * */#include "picture.h"#include "event.h"#include <jpeglib.h>#include <jerror.h>/* The following declarations and 5 functions are jpeg related * functions used by put_jpeg_grey_memory and put_jpeg_yuv420p_memory */typedef struct { struct jpeg_destination_mgr pub; JOCTET *buf; size_t bufsize; size_t jpegsize;} mem_destination_mgr;typedef mem_destination_mgr *mem_dest_ptr;METHODDEF(void) init_destination(j_compress_ptr cinfo){ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; dest->pub.next_output_byte = dest->buf; dest->pub.free_in_buffer = dest->bufsize; dest->jpegsize = 0;}METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo){ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; dest->pub.next_output_byte = dest->buf; dest->pub.free_in_buffer = dest->bufsize; return FALSE; ERREXIT(cinfo, JERR_BUFFER_SIZE);}METHODDEF(void) term_destination(j_compress_ptr cinfo){ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; dest->jpegsize = dest->bufsize - dest->pub.free_in_buffer;}static GLOBAL(void) jpeg_mem_dest(j_compress_ptr cinfo, JOCTET* buf, size_t bufsize){ mem_dest_ptr dest; if (cinfo->dest == NULL) { cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(mem_destination_mgr)); } dest = (mem_dest_ptr) cinfo->dest; dest->pub.init_destination = init_destination; dest->pub.empty_output_buffer = empty_output_buffer; dest->pub.term_destination = term_destination; dest->buf = buf; dest->bufsize = bufsize; dest->jpegsize = 0;}static GLOBAL(int) jpeg_mem_size(j_compress_ptr cinfo){ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; return dest->jpegsize;}/* put_jpeg_yuv420p_memory converts an input image in the YUV420P format into a jpeg image and puts * it in a memory buffer. * Inputs: * - image_size is the size of the input image buffer. * - input_image is the image in YUV420P format. * - width and height are the dimensions of the image * - quality is the jpeg encoding quality 0-100% * Output: * - dest_image is a pointer to the jpeg image buffer * Returns buffer size of jpeg image */static int put_jpeg_yuv420p_memory(unsigned char *dest_image, int image_size, unsigned char *input_image, int width, int height, int quality){ int i, j, jpeg_image_size; JSAMPROW y[16],cb[16],cr[16]; // y[2][5] = color sample of row 2 and pixel column 5; (one plane) JSAMPARRAY data[3]; // t[0][2][5] = color sample 0 of row 2 and column 5 struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; data[0] = y; data[1] = cb; data[2] = cr; cinfo.err = jpeg_std_error(&jerr); // errors get written to stderr jpeg_create_compress(&cinfo); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; jpeg_set_defaults (&cinfo); jpeg_set_colorspace(&cinfo, JCS_YCbCr); cinfo.raw_data_in = TRUE; // supply downsampled data cinfo.comp_info[0].h_samp_factor = 2; cinfo.comp_info[0].v_samp_factor = 2; cinfo.comp_info[1].h_samp_factor = 1; cinfo.comp_info[1].v_samp_factor = 1; cinfo.comp_info[2].h_samp_factor = 1; cinfo.comp_info[2].v_samp_factor = 1; jpeg_set_quality(&cinfo, quality, TRUE); cinfo.dct_method = JDCT_FASTEST; jpeg_mem_dest(&cinfo, dest_image, image_size); // data written to mem jpeg_start_compress (&cinfo, TRUE); for (j=0; j<height; j+=16) { for (i=0; i<16; i++) { y[i] = input_image + width*(i+j); if (i%2 == 0) { cb[i/2] = input_image + width*height + width/2*((i+j)/2); cr[i/2] = input_image + width*height + width*height/4 + width/2*((i+j)/2); } } jpeg_write_raw_data(&cinfo, data, 16); } jpeg_finish_compress(&cinfo); jpeg_image_size = jpeg_mem_size(&cinfo); jpeg_destroy_compress(&cinfo); return jpeg_image_size;}/* put_jpeg_grey_memory converts an input image in the grayscale format into a jpeg image * Inputs: * - image_size is the size of the input image buffer. * - input_image is the image in grayscale format. * - width and height are the dimensions of the image * - quality is the jpeg encoding quality 0-100% * Output: * - dest_image is a pointer to the jpeg image buffer * Returns buffer size of jpeg image */static int put_jpeg_grey_memory(unsigned char *dest_image, int image_size, unsigned char *input_image, int width, int height, int quality){ int y, dest_image_size; JSAMPROW row_ptr[1]; struct jpeg_compress_struct cjpeg; struct jpeg_error_mgr jerr; cjpeg.err = jpeg_std_error(&jerr); jpeg_create_compress(&cjpeg); cjpeg.image_width = width; cjpeg.image_height = height; cjpeg.input_components = 1; /* one colour component */ cjpeg.in_color_space = JCS_GRAYSCALE; jpeg_set_defaults(&cjpeg); jpeg_set_quality(&cjpeg, quality, TRUE); cjpeg.dct_method = JDCT_FASTEST; jpeg_mem_dest(&cjpeg, dest_image, image_size); // data written to mem jpeg_start_compress (&cjpeg, TRUE); row_ptr[0] = input_image; for (y=0; y<height; y++) { jpeg_write_scanlines(&cjpeg, row_ptr, 1); row_ptr[0] += width; } jpeg_finish_compress(&cjpeg); dest_image_size = jpeg_mem_size(&cjpeg); jpeg_destroy_compress(&cjpeg); return dest_image_size;}/* put_jpeg_yuv420p_file converts an YUV420P coded image to a jpeg image and writes * it to an already open file. * Inputs: * - image is the image in YUV420P format. * - width and height are the dimensions of the image * - quality is the jpeg encoding quality 0-100% * Output: * - The jpeg is written directly to the file given by the file pointer fp * Returns nothing */static void put_jpeg_yuv420p_file(FILE *fp, unsigned char *image, int width, int height, int quality){ int i,j; JSAMPROW y[16],cb[16],cr[16]; // y[2][5] = color sample of row 2 and pixel column 5; (one plane) JSAMPARRAY data[3]; // t[0][2][5] = color sample 0 of row 2 and column 5 struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; data[0] = y; data[1] = cb; data[2] = cr; cinfo.err = jpeg_std_error(&jerr); // errors get written to stderr jpeg_create_compress(&cinfo); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; jpeg_set_defaults(&cinfo); jpeg_set_colorspace(&cinfo, JCS_YCbCr); cinfo.raw_data_in = TRUE; // supply downsampled data cinfo.comp_info[0].h_samp_factor = 2; cinfo.comp_info[0].v_samp_factor = 2; cinfo.comp_info[1].h_samp_factor = 1; cinfo.comp_info[1].v_samp_factor = 1; cinfo.comp_info[2].h_samp_factor = 1; cinfo.comp_info[2].v_samp_factor = 1; jpeg_set_quality(&cinfo, quality, TRUE); cinfo.dct_method = JDCT_FASTEST; jpeg_stdio_dest(&cinfo, fp); // data written to file jpeg_start_compress(&cinfo, TRUE); for (j=0;j<height;j+=16) { for (i=0;i<16;i++) { y[i] = image + width*(i+j); if (i%2 == 0) { cb[i/2] = image + width*height + width/2*((i+j)/2); cr[i/2] = image + width*height + width*height/4 + width/2*((i+j)/2); } } jpeg_write_raw_data(&cinfo, data, 16); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo);}/* put_jpeg_grey_file converts an greyscale image to a jpeg image and writes * it to an already open file. * Inputs: * - image is the image in greyscale format. * - width and height are the dimensions of the image * - quality is the jpeg encoding quality 0-100% * Output: * - The jpeg is written directly to the file given by the file pointer fp * Returns nothing */static void put_jpeg_grey_file(FILE *picture, unsigned char *image, int width, int height, int quality){ int y; JSAMPROW row_ptr[1]; struct jpeg_compress_struct cjpeg; struct jpeg_error_mgr jerr; cjpeg.err = jpeg_std_error(&jerr); jpeg_create_compress(&cjpeg); cjpeg.image_width = width; cjpeg.image_height = height; cjpeg.input_components = 1; /* one colour component */ cjpeg.in_color_space = JCS_GRAYSCALE; jpeg_set_defaults(&cjpeg); jpeg_set_quality(&cjpeg, quality, TRUE); cjpeg.dct_method = JDCT_FASTEST; jpeg_stdio_dest(&cjpeg, picture); jpeg_start_compress(&cjpeg, TRUE); row_ptr[0]=image; for (y=0; y<height; y++) { jpeg_write_scanlines(&cjpeg, row_ptr, 1); row_ptr[0]+=width; } jpeg_finish_compress(&cjpeg); jpeg_destroy_compress(&cjpeg);}/* put_ppm_bgr24_file converts an greyscale image to a PPM image and writes * it to an already open file. * Inputs: * - image is the image in YUV420P format. * - width and height are the dimensions of the image * Output: * - The PPM is written directly to the file given by the file pointer fp * Returns nothing */static void put_ppm_bgr24_file(FILE *picture, unsigned char *image, int width, int height){ int x, y; unsigned char *l=image; unsigned char *u=image+width*height; unsigned char *v=u+(width*height)/4; int r, g, b; int warningkiller; unsigned char rgb[3]; /* ppm header * width height * maxval */ fprintf(picture, "P6\n"); fprintf(picture, "%d %d\n", width, height); fprintf(picture, "%d\n", 255); for (y=0; y<height; y++) { for (x=0; x<width; x++) { r = 76283*(((int)*l)-16)+104595*(((int)*u)-128); g = 76283*(((int)*l)-16)- 53281*(((int)*u)-128)-25625*(((int)*v)-128); b = 76283*(((int)*l)-16)+132252*(((int)*v)-128); r = r>>16; g = g>>16; b = b>>16; if (r<0) r=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -