static int jpeg_encode_yuv_row(u8* output, int quality, image_data_t input) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; int i = 0; int j = 0; int written = 0; u32 size = input.width * input.height; u32 quarter_size = size / 4; u32 row = 0; JSAMPROW y[16]; JSAMPROW cb[16]; JSAMPROW cr[16]; JSAMPARRAY planes[3]; planes[0] = y; planes[1] = cb; planes[2] = cr; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); dest_buffer(&cinfo, output, input.width * input.height, &written); cinfo.image_width = input.width; /* image width and height, in pixels */ cinfo.image_height = input.height; cinfo.input_components = COLOR_COMPONENTS; /* # of color components per pixel */ cinfo.in_color_space = JCS_YCbCr; /* colorspace of input image */ jpeg_set_defaults(&cinfo); cinfo.raw_data_in = TRUE; // supply downsampled data cinfo.dct_method = JDCT_IFAST; 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 /* limit to baseline-JPEG values */); jpeg_start_compress(&cinfo, TRUE); for (j = 0; j < input.height; j += 16) { for (i = 0; i < 16; i++) { row = input.width * (i + j); y[i] = input.buffer + row; if (i % 2 == 0) { cb[i/2] = input.buffer + size + row/4; cr[i/2] = input.buffer + size + quarter_size + row/4; } } jpeg_write_raw_data(&cinfo, planes, 16); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); return written; }
int jpeg_utils::compress_rgb_to_jpeg(Image *src, unsigned char* buffer, int size, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; unsigned char *line_buffer, *rgb; int z; static int written; line_buffer = (unsigned char*)calloc (src->m_Width * 3, 1); rgb = src->m_ImageData; cinfo.err = jpeg_std_error (&jerr); jpeg_create_compress (&cinfo); /* jpeg_stdio_dest (&cinfo, file); */ dest_buffer(&cinfo, buffer, size, &written); cinfo.image_width = src->m_Width; cinfo.image_height = src->m_Height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults (&cinfo); jpeg_set_quality (&cinfo, quality, TRUE); jpeg_start_compress (&cinfo, TRUE); z = 0; while (cinfo.next_scanline < src->m_Height) { int x; unsigned char *ptr = line_buffer; for (x = 0; x < src->m_Width; x++) { int r, g, b; r = rgb[0]; g = rgb[1]; b = rgb[2]; *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r); *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g); *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b); rgb += 3; } row_pointer[0] = line_buffer; jpeg_write_scanlines (&cinfo, row_pointer, 1); } jpeg_finish_compress (&cinfo); jpeg_destroy_compress (&cinfo); free (line_buffer); return (written); }
/****************************************************************************** Description.: yuv2jpeg function is based on compress_yuyv_to_jpeg written by Gabriel A. Devenyi. modified to support other formats like RGB5:6:5 by Miklós Márton It uses the destination manager implemented above to compress YUYV data to JPEG. Most other implementations use the "jpeg_stdio_dest" from libjpeg, which can not store compressed pictures to memory instead of a file. Input Value.: video structure from v4l2uvc.c/h, destination buffer and buffersize the buffer must be large enough, no error/size checking is done! Return Value: the buffer will contain the compressed data ******************************************************************************/ int compress_image_to_jpeg(const unsigned char *yuyvBuffer,MSPixFmt formatIn, int width,int height, unsigned char *outBuffer, int size, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; unsigned char *line_buffer, *yuyv; int z; static int written; line_buffer = calloc(width * 3, 1); yuyv = yuyvBuffer; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); /* jpeg_stdio_dest (&cinfo, file); */ dest_buffer(&cinfo, outBuffer, size, &written); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; if (formatIn == MS_YUYV) cinfo.in_color_space = JCS_RGB; else if (formatIn == MS_YUV420P) cinfo.in_color_space = JCS_YCbCr; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); z = 0; if (formatIn == MS_YUYV) { jpeg_start_compress(&cinfo, TRUE); while(cinfo.next_scanline < height) { int x; unsigned char *ptr = line_buffer; for(x = 0; x < width; x++) { int r, g, b; int y, u, v; if(!z) y = yuyv[0] << 8; else y = yuyv[2] << 8; u = yuyv[1] - 128; v = yuyv[3] - 128; r = (y + (359 * v)) >> 8; g = (y - (88 * u) - (183 * v)) >> 8; b = (y + (454 * u)) >> 8; *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r); *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g); *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b); if(z++) { z = 0; yuyv += 4; } } row_pointer[0] = line_buffer; jpeg_write_scanlines(&cinfo, row_pointer, 1); } } else if(formatIn == MS_YUV420P)
int jpeg_utils::compress_yuyv_to_jpeg(Image *src, unsigned char* buffer, int size, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; unsigned char *line_buffer, *yuyv; int z; static int written; line_buffer = (unsigned char*)calloc (src->m_Width * 3, 1); yuyv = src->m_ImageData; cinfo.err = jpeg_std_error (&jerr); jpeg_create_compress (&cinfo); /* jpeg_stdio_dest (&cinfo, file); */ dest_buffer(&cinfo, buffer, size, &written); cinfo.image_width = src->m_Width; cinfo.image_height = src->m_Height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults (&cinfo); jpeg_set_quality (&cinfo, quality, TRUE); jpeg_start_compress (&cinfo, TRUE); z = 0; while (cinfo.next_scanline < src->m_Height) { int x; unsigned char *ptr = line_buffer; for (x = 0; x < src->m_Width; x++) { int r, g, b; int y, u, v; if (!z) y = yuyv[0] << 8; else y = yuyv[2] << 8; u = yuyv[1] - 128; v = yuyv[3] - 128; r = (y + (359 * v)) >> 8; g = (y - (88 * u) - (183 * v)) >> 8; b = (y + (454 * u)) >> 8; *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r); *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g); *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b); if (z++) { z = 0; yuyv += 4; } } row_pointer[0] = line_buffer; jpeg_write_scanlines (&cinfo, row_pointer, 1); } jpeg_finish_compress (&cinfo); jpeg_destroy_compress (&cinfo); free (line_buffer); return (written); }
/****************************************************************************** Description.: yuv2jpeg function is based on compress_yuyv_to_jpeg written by Gabriel A. Devenyi. modified to support other formats like RGB5:6:5 by Miklós Márton It uses the destination manager implemented above to compress YUYV data to JPEG. Most other implementations use the "jpeg_stdio_dest" from libjpeg, which can not store compressed pictures to memory instead of a file. Input Value.: video structure from v4l2uvc.c/h, destination buffer and buffersize the buffer must be large enough, no error/size checking is done! Return Value: the buffer will contain the compressed data ******************************************************************************/ int compress_image_to_jpeg(struct vdIn *vd, unsigned char *buffer, int size, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW *row_pointer; unsigned char *line_buffer, *yuyv; int z; static int written; line_buffer = calloc(vd->width * 3, 1); yuyv = vd->framebuffer; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); /* jpeg_stdio_dest (&cinfo, file); */ dest_buffer(&cinfo, buffer, size, &written); cinfo.image_width = vd->width; cinfo.image_height = vd->height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); jpeg_start_compress(&cinfo, TRUE); z = 0; if (vd->formatIn == V4L2_PIX_FMT_YUYV) { while(cinfo.next_scanline < vd->height) { int x; unsigned char *ptr = line_buffer; for(x = 0; x < vd->width; x++) { int r, g, b; int y, u, v; if(!z) y = yuyv[0] << 8; else y = yuyv[2] << 8; u = yuyv[1] - 128; v = yuyv[3] - 128; r = (y + (359 * v)) >> 8; g = (y - (88 * u) - (183 * v)) >> 8; b = (y + (454 * u)) >> 8; *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r); *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g); *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b); if(z++) { z = 0; yuyv += 4; } } row_pointer = (JSAMPROW*)line_buffer; jpeg_write_scanlines(&cinfo, row_pointer, 1); } } else if (vd->formatIn == V4L2_PIX_FMT_RGB565) {
size_t MJPEGStreamer::compress_yuyv_to_jpeg(const YUVImage& src, uint8_t* buffer, size_t size, int quality) const { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; uint8_t *line_buffer; const uint8_t *yuyv; int z; static size_t written; line_buffer = (uint8_t*)calloc((size_t)(uint32_t)(src.getWidth() * 3), (size_t)1); if (line_buffer == NULL) { return 0; } yuyv = (const uint8_t*)src.getImage(); cinfo.err = jpeg_std_error (&jerr); jpeg_create_compress (&cinfo); /* jpeg_stdio_dest (&cinfo, file); */ dest_buffer(&cinfo, buffer, size, &written); cinfo.image_width = (uint32_t)src.getWidth(); cinfo.image_height = (uint32_t)src.getHeight(); cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults (&cinfo); jpeg_set_quality (&cinfo, quality, TRUE); jpeg_start_compress (&cinfo, TRUE); z = 0; while (cinfo.next_scanline < (uint32_t)src.getHeight()) { int x; uint8_t *ptr = line_buffer; for (x = 0; x < src.getWidth(); x++) { int r, g, b; int y, u, v; if (!z) y = yuyv[0] << 8; else y = yuyv[2] << 8; u = yuyv[1] - 128; v = yuyv[3] - 128; //lint -e{702} r = (y + (359 * v)) >> 8; //lint -e{702} g = ((y - (88 * u)) - (183 * v)) >> 8; //lint -e{702} b = (y + (454 * u)) >> 8; *(ptr++) = (uint8_t)((r > 255) ? 255 : ((r < 0) ? 0 : r)); *(ptr++) = (uint8_t)((g > 255) ? 255 : ((g < 0) ? 0 : g)); *(ptr++) = (uint8_t)((b > 255) ? 255 : ((b < 0) ? 0 : b)); if (z++) { z = 0; yuyv += 4; } } row_pointer[0] = line_buffer; jpeg_write_scanlines (&cinfo, row_pointer, 1); } jpeg_finish_compress (&cinfo); jpeg_destroy_compress (&cinfo); free (line_buffer); return (written); }
//buffer = pglobal->in[pcontext->id].buf //fread(src_data,sizeof(unsigned char)*image_size,1,bmpfile); //remember free(src_data); //vd->width = image_width int image_width,image_height,image_size,bits_per_pixel,headersize,depth; int compress_bmp_to_jpeg(unsigned char *buffer,int quality) { //copy from jpeg_utils struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; //unsigned char *line_buffer, *yuyv; unsigned char *dst_data; int i,j; static int written; int row_stride; //line_buffer = calloc(vd->width * 3, 1); //yuyv = vd->framebuffer; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); /* jpeg_stdio_dest (&cinfo, file); */ dest_buffer(&cinfo, buffer, image_size, &written); //cinfo.image_width = vd->width; //cinfo.image_height = vd->height; //cinfo.input_components = 3; //cinfo.in_color_space = JCS_RGB; cinfo.image_width = image_width; /* image width and height, in pixels */ cinfo.image_height = image_height; cinfo.input_components = depth; /* # of color components per pixel */ cinfo.in_color_space = (depth==3) ? JCS_RGB : JCS_GRAYSCALE; /* colorspace of input image */ jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); printf("test ======\n"); printf("8888888888888888888888888888888888888888\n"); dst_data=(unsigned char *)malloc(image_size*sizeof(unsigned char)); //调整rgb顺序bgr->rgb for(i=0;i<image_height;i++){ for(j=0;j<image_width;j++) { if(depth==1)//灰度图 *(dst_data+i*image_width+j)=*(src_data+i*image_width+j); else //真彩图 { *(dst_data+i*image_width*depth+j*3+0)=*(src_data+i*image_width*depth+j*3+2); *(dst_data+i*image_width*depth+j*3+1)=*(src_data+i*image_width*depth+j*3+1); *(dst_data+i*image_width*depth+j*3+2)=*(src_data+i*image_width*depth+j*3+0); } } } jpeg_start_compress(&cinfo, TRUE); printf("test ======\n"); row_stride = image_width * cinfo.input_components; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & dst_data[(cinfo.image_height - cinfo.next_scanline - 1) * row_stride];//cinfo.next_scanline * row_stride (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); //free(line_buffer); free(src_data); free(dst_data); return (written); }