Mercurial > hg > minimon
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