📄 compress.cpp
字号:
/*
Robot Interface
(C) 2006 Jason Hunt
nulluser@gmail.com
File: compress.h
You have to wrap jpeglib.h in extern "C" { }
*/
#include <stdio.h>
#include <jpeglib.h>
#include <jconfig.h>
#include <jerror.h>
#include "camera.h"
unsigned int max_buffer; // The size of the buffer that the caller is maintaining
char *c_buffer; // Pointer to the compressed buffer
unsigned int out_size; // Size of the compressed object
typedef struct { // Simple destination manager
struct jpeg_destination_mgr pub;
} buffer_mgr;
typedef buffer_mgr * dest_ptr;
/* Called on startup to setup destination*/
METHODDEF(void) buffer_init_destination (j_compress_ptr cinfo)
{
dest_ptr dest = (dest_ptr) cinfo->dest;
// Point to start of buffer
dest->pub.next_output_byte = (JOCTET *) c_buffer;
// Set buffer size
dest->pub.free_in_buffer = max_buffer;
}
/* End of buffer_init_destination */
/* Write the compressed data to the buffer */
METHODDEF(boolean) buffer_empty_output_buffer (j_compress_ptr cinfo)
{
// Not needed, we are writing directly to a buffer
return(TRUE);
}
/* End of buffer_empty_output_buffer */
/* Called for cleanup */
METHODDEF(void) buffer_term_destination (j_compress_ptr cinfo)
{
dest_ptr dest = (dest_ptr) cinfo->dest;
out_size += max_buffer - dest->pub.free_in_buffer;
}
/* End of buffer_term_destination */
/* Eetup for buffer compress */
GLOBAL(void) jpeg_buffer_dest (j_compress_ptr cinfo, char *buffer, unsigned int max)
{
dest_ptr dest; // Pointer to destination structure
out_size = 0; // Reset the outsize
max_buffer = max; // Set max buffer size
c_buffer = buffer; // Link the buffer
/* Create the structure */
if (cinfo->dest == NULL)
{
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(buffer_mgr));
}
dest = (dest_ptr) cinfo->dest;
dest->pub.init_destination = buffer_init_destination;
dest->pub.empty_output_buffer = buffer_empty_output_buffer;
dest->pub.term_destination = buffer_term_destination;
}
/* End of buffer_dest */
/* Transcode the image into 3 byte configuration */
void convert_4byte_to_3byte(unsigned char *in, unsigned char *out, unsigned int size)
{
unsigned int out_index = 0, in_index = 0;
for (unsigned int i = 0; i < size; i++)
{
out[out_index++] = in[in_index++];
out[out_index++] = in[in_index++];
out[out_index++] = in[in_index++];
in_index++;
}
}
/* End of convert_4byte_to_3byte */
/* Use ligjpeg to compress the image */
void compress_frame(byte *image,
byte *compressed,
byte *transcode_buffer,
int max, unsigned int *the_out_size, int x_size, int y_size)
{
if (x_size == 0 || y_size == 0) return;
convert_4byte_to_3byte(image, (byte *)transcode_buffer, x_size * y_size);
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1]; // Pointer to JSAMPLE rows
int row_stride; // Physical row width in image buffer
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_buffer_dest(&cinfo, (char *)compressed, max);
cinfo.image_width = x_size; // Set image size
cinfo.image_height = y_size;
cinfo.input_components = 3; // Number of color components per pixel
cinfo.in_color_space = JCS_RGB; // RGB
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 80, TRUE ); // 80 percent quality
jpeg_start_compress(&cinfo, TRUE);
row_stride = x_size * cinfo.input_components; // JSAMPLEs per row in image_buffer
// Core compression loop
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = (JSAMPLE *) &transcode_buffer[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
// Set actual output size
*the_out_size = out_size;
jpeg_destroy_compress(&cinfo);/**/
}
/* End of compress_frame */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -