diff jpg.c @ 10:078dc69945ad

working: libjpeg-turbo support, handle fb and monitor with different size
author Peter Meerwald <pmeerw@pmeerw.net>
date Sun, 15 May 2011 17:48:57 +0200
parents 66c77f9ba9b9
children
line wrap: on
line diff
--- a/jpg.c	Sat May 14 23:08:11 2011 +0200
+++ b/jpg.c	Sun May 15 17:48:57 2011 +0200
@@ -92,17 +92,8 @@
   dest->pub.free_in_buffer = dest->bufsize = *outsize;
 }
 
-static void convert_rgba_to_rgb(unsigned char *buf, unsigned char *fb_mem, int width) {
-  int i;
-  for (i = 0; i < width; i++) {
-    *buf++ = *fb_mem++;
-    *buf++ = *fb_mem++;
-    *buf++ = *fb_mem++;
-    fb_mem++;
-  }
-}
-
-jpg_buf_t build_jpg_from_fb(unsigned char *fb_mem, int width, int height, int bits_per_pixel) {
+#ifdef HAVE_LIBJPEG_TURBO
+jpg_buf_t build_jpg_from_fb(unsigned char *fb_mem, int fb_width, int fb_height, int bits_per_pixel, int mon_width, int mon_height) {
   int scanline;
   struct jpeg_compress_struct cinfo;
   struct jpeg_error_mgr jerr;
@@ -116,21 +107,34 @@
 
   my_jpeg_mem_dest(&cinfo, &jpg_buf.ptr, &jpg_buf.size);
 
-  cinfo.image_width = width;
-  cinfo.image_height = height;
-  cinfo.input_components = 3;
-  cinfo.in_color_space = JCS_RGB;
+  cinfo.image_width = mon_width;
+  cinfo.image_height = mon_height;
+  cinfo.input_components = 4;
+  cinfo.in_color_space = JCS_EXT_BGRX;
   jpeg_set_defaults(&cinfo);
-
+  cinfo.dct_method = JDCT_FASTEST;
+  jpeg_set_quality(&cinfo, 70, TRUE);
+  
   jpeg_start_compress(&cinfo, TRUE);
 
-  JSAMPLE *buf = (JSAMPLE *) malloc(width * 3);
+  unsigned char buf[mon_width * 4];
   JSAMPROW row_ptr[1] = {buf};
-  for (scanline = 0; scanline < height; scanline++) {
-    convert_rgba_to_rgb(buf, &fb_mem[scanline * width * 4], width);
+  memset(buf, 0, mon_width*4);
+  if (fb_width >= mon_width)
+    for (scanline = 0; scanline < MIN(fb_height, mon_height); scanline++) {
+      row_ptr[0] = &fb_mem[scanline * fb_width * 4];
+      jpeg_write_scanlines(&cinfo, row_ptr, 1);
+    }
+  else {
+    for (scanline = 0; scanline < MIN(fb_height, mon_height); scanline++) {
+      memcpy(buf, &fb_mem[scanline * fb_width * 4], fb_width * 4);
+      jpeg_write_scanlines(&cinfo, row_ptr, 1);
+    }
+  }
+  memset(buf, 0, mon_width*4);
+  for (scanline = fb_height; scanline < mon_height; scanline++) {
     jpeg_write_scanlines(&cinfo, row_ptr, 1);
   }
-  free(buf);
 
   jpeg_finish_compress(&cinfo);
 
@@ -138,3 +142,59 @@
 
   return jpg_buf;
 }
+#else
+static void convert_rgba_to_rgb(unsigned char *buf, unsigned char *fb_mem, int width) {
+  int i;
+  for (i = 0; i < width; i++) {
+// BGRX
+    unsigned int x = *(unsigned int *)fb_mem;
+    *buf++ = (x >> 16) & 0xff;
+    *buf++ = (x >> 8) & 0xff;
+    *buf++ = (x) & 0xff;
+    fb_mem += 4;
+  }
+}
+
+jpg_buf_t build_jpg_from_fb(unsigned char *fb_mem, int fb_width, int fb_height, int bits_per_pixel, int mon_width, int mon_height) {
+  int scanline;
+  struct jpeg_compress_struct cinfo;
+  struct jpeg_error_mgr jerr;
+  
+  cinfo.err = jpeg_std_error(&jerr);
+  jpeg_create_compress(&cinfo);
+
+  jpg_buf_t jpg_buf;
+  jpg_buf.size = 1 << 20;
+  jpg_buf.ptr = NULL;
+
+  my_jpeg_mem_dest(&cinfo, &jpg_buf.ptr, &jpg_buf.size);
+
+  cinfo.image_width = mon_width;
+  cinfo.image_height = mon_height;
+  cinfo.input_components = 3;
+  cinfo.in_color_space = JCS_RGB;
+  jpeg_set_defaults(&cinfo);
+  cinfo.dct_method = JDCT_FASTEST;
+  jpeg_set_quality(&cinfo, 70, TRUE);
+  
+  jpeg_start_compress(&cinfo, TRUE);
+
+  JSAMPLE buf[mon_width * 3];
+  JSAMPROW row_ptr[1] = {buf};
+  memset(buf, 0, mon_width*3);
+  for (scanline = 0; scanline < MIN(fb_height, mon_height); scanline++) {
+    convert_rgba_to_rgb(buf, &fb_mem[scanline * fb_width * 4], mon_width);
+    jpeg_write_scanlines(&cinfo, row_ptr, 1);
+  }
+  memset(buf, 0, mon_width*3);
+  for (scanline = fb_height; scanline < mon_height; scanline++) {
+    jpeg_write_scanlines(&cinfo, row_ptr, 1);
+  }
+
+  jpeg_finish_compress(&cinfo);
+
+  jpeg_destroy_compress(&cinfo);
+
+  return jpg_buf;
+}
+#endif

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.