Hi, Is it a patch against libjpeg v6b or the newer v7 (scale_denom goes till 16)?
-Ilyes On Fri, Sep 4, 2009 at 11:43 AM, Sven Neumann<s.neum...@raumfeld.com> wrote: > We can speed up scaled-down rendering of JPEG images by asking libjpeg > to only decode the image to a fraction of the original size. > --- > .../idirectfbimageprovider_jpeg.c | 79 > +++++++++++++------- > 1 files changed, 52 insertions(+), 27 deletions(-) > > diff --git a/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c > b/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c > index e67da17..6b6aef3 100644 > --- a/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c > +++ b/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c > @@ -83,9 +83,12 @@ typedef struct { > DIRenderCallback render_callback; > void *render_callback_context; > > - u32 *image; > - int width; > - int height; > + int width; /* width of the JPEG image */ > + int height; /* height of the JPEG image */ > + > + u32 *image; /* decoded image data */ > + int image_width; /* width of image data */ > + int image_height; /* height of image data */ > > CoreDFB *core; > } IDirectFBImageProvider_JPEG_data; > @@ -157,7 +160,7 @@ buffer_fill_input_buffer (j_decompress_ptr cinfo) > else { > ret = buffer->GetData( buffer, JPEG_PROG_BUF_SIZE, src->data, > &nbytes ); > } > - > + > if (ret || nbytes <= 0) { > /* Insert a fake EOI marker */ > src->data[0] = (JOCTET) 0xFF; > @@ -302,7 +305,7 @@ Construct( IDirectFBImageProvider *thiz, > { > struct jpeg_decompress_struct cinfo; > struct my_error_mgr jerr; > - > + > IDirectFBDataBuffer *buffer; > CoreDFB *core; > va_list tag; > @@ -336,10 +339,10 @@ Construct( IDirectFBImageProvider *thiz, > jpeg_buffer_src(&cinfo, buffer, 1); > jpeg_read_header(&cinfo, TRUE); > jpeg_start_decompress(&cinfo); > - > + > data->width = cinfo.output_width; > data->height = cinfo.output_height; > - > + > jpeg_abort_decompress(&cinfo); > jpeg_destroy_decompress(&cinfo); > > @@ -424,7 +427,7 @@ IDirectFBImageProvider_JPEG_RenderTo( > IDirectFBImageProvider *thiz, > if (dest_rect) { > if (dest_rect->w < 1 || dest_rect->h < 1) > return DFB_INVARG; > - > + > rect = *dest_rect; > rect.x += dst_data->area.wanted.x; > rect.y += dst_data->area.wanted.y; > @@ -440,6 +443,14 @@ IDirectFBImageProvider_JPEG_RenderTo( > IDirectFBImageProvider *thiz, > if (ret) > return ret; > > + if (data->image && > + (rect.x || rect.y || rect.w != data->image_width || rect.h != > data->image_height)) { > + D_FREE( data->image ); > + data->image = NULL; > + data->image_width = 0; > + data->image_height = 0; > + } > + > /* actual loading and rendering */ > if (!data->image) { > struct jpeg_decompress_struct cinfo; > @@ -459,11 +470,11 @@ IDirectFBImageProvider_JPEG_RenderTo( > IDirectFBImageProvider *thiz, > jpeg_destroy_decompress(&cinfo); > > if (data->image) { > - dfb_scale_linear_32( data->image, data->width, > data->height, > + dfb_scale_linear_32( data->image, data->image_width, > data->image_height, > lock.addr, lock.pitch, &rect, > dst_surface, &clip ); > dfb_surface_unlock_buffer( dst_surface, &lock ); > if (data->render_callback) { > - DFBRectangle r = { 0, 0, data->width, data->height > }; > + DFBRectangle r = { 0, 0, data->image_width, > data->image_height }; > > if (data->render_callback( &r, > data->render_callback_context ) != DIRCR_OK) > return DFB_INTERRUPTED; > @@ -480,10 +491,24 @@ IDirectFBImageProvider_JPEG_RenderTo( > IDirectFBImageProvider *thiz, > jpeg_create_decompress(&cinfo); > jpeg_buffer_src(&cinfo, data->buffer, 0); > jpeg_read_header(&cinfo, TRUE); > + > + cinfo.scale_num = 1; > + cinfo.scale_denom = 1; > jpeg_calc_output_dimensions(&cinfo); > > - if (cinfo.output_width == rect.w && cinfo.output_height == rect.h) > + data->width = cinfo.output_width; > + data->height = cinfo.output_height; > + > + if (cinfo.output_width == rect.w && cinfo.output_height == rect.h) > { > direct = true; > + } > + else if (rect.x == 0 && rect.y == 0) { > + while (cinfo.scale_denom < 16 && > + (cinfo.output_width >> 1) > rect.w && > (cinfo.output_height >> 1) > rect.h) { > + cinfo.scale_denom <<= 1; > + jpeg_calc_output_dimensions (&cinfo); > + } > + } > > cinfo.output_components = 3; > > @@ -499,7 +524,7 @@ IDirectFBImageProvider_JPEG_RenderTo( > IDirectFBImageProvider *thiz, > } > D_INFO( "JPEG: Going through RGB color space! (%dx%d -> > %dx%d @%d,%d)\n", > cinfo.output_width, cinfo.output_height, rect.w, > rect.h, rect.x, rect.y ); > - > + > default: > cinfo.out_color_space = JCS_RGB; > break; > @@ -507,15 +532,15 @@ IDirectFBImageProvider_JPEG_RenderTo( > IDirectFBImageProvider *thiz, > > jpeg_start_decompress(&cinfo); > > - data->width = cinfo.output_width; > - data->height = cinfo.output_height; > + data->image_width = cinfo.output_width; > + data->image_height = cinfo.output_height; > > row_stride = cinfo.output_width * 3; > > buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, > JPOOL_IMAGE, row_stride, 1); > > - data->image = D_CALLOC( data->height, data->width * 4 ); > + data->image = D_CALLOC( data->image_height, data->image_width * 4 > ); > if (!data->image) { > dfb_surface_unlock_buffer( dst_surface, &lock ); > return D_OOM(); > @@ -533,39 +558,39 @@ IDirectFBImageProvider_JPEG_RenderTo( > IDirectFBImageProvider *thiz, > lock.addr += lock.pitch; > > if (data->render_callback) { > - DFBRectangle r = { 0, y, data->width, 1 }; > + DFBRectangle r = { 0, y, > data->image_width, 1 }; > > - cb_result = data->render_callback( &r, > + cb_result = data->render_callback( &r, > > data->render_callback_context ); > } > break; > } > > default: > - copy_line32( row_ptr, *buffer, data->width); > + copy_line32( row_ptr, *buffer, data->image_width); > > if (direct) { > DFBRectangle r = { rect.x, rect.y+y, rect.w, 1 > }; > dfb_copy_buffer_32( row_ptr, lock.addr, > lock.pitch, > &r, dst_surface, &clip ); > if (data->render_callback) { > - r = (DFBRectangle){ 0, y, data->width, 1 > }; > - cb_result = data->render_callback( &r, > + r = (DFBRectangle){ 0, y, > data->image_width, 1 }; > + cb_result = data->render_callback( &r, > > data->render_callback_context ); > } > } > break; > } > > - row_ptr += data->width; > + row_ptr += data->image_width; > y++; > } > > if (!direct) { > - dfb_scale_linear_32( data->image, data->width, data->height, > + dfb_scale_linear_32( data->image, data->image_width, > data->image_height, > lock.addr, lock.pitch, &rect, > dst_surface, &clip ); > if (data->render_callback) { > - DFBRectangle r = { 0, 0, data->width, data->height }; > + DFBRectangle r = { 0, 0, data->image_width, > data->image_height }; > cb_result = data->render_callback( &r, > data->render_callback_context ); > } > } > @@ -581,14 +606,14 @@ IDirectFBImageProvider_JPEG_RenderTo( > IDirectFBImageProvider *thiz, > jpeg_destroy_decompress(&cinfo); > } > else { > - dfb_scale_linear_32( data->image, data->width, data->height, > + dfb_scale_linear_32( data->image, data->image_width, > data->image_height, > lock.addr, lock.pitch, &rect, dst_surface, > &clip ); > if (data->render_callback) { > - DFBRectangle r = { 0, 0, data->width, data->height }; > + DFBRectangle r = { 0, 0, data->image_width, > data->image_height }; > data->render_callback( &r, data->render_callback_context ); > } > } > - > + > dfb_surface_unlock_buffer( dst_surface, &lock ); > > if (cb_result != DIRCR_OK) > @@ -615,7 +640,7 @@ IDirectFBImageProvider_JPEG_GetSurfaceDescription( > IDirectFBImageProvider *thiz, > DFBSurfaceDescription > *dsc ) > { > DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) > - > + > dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; > dsc->height = data->height; > dsc->width = data->width; > -- > 1.6.0.4 > > _______________________________________________ > directfb-dev mailing list > directfb-dev@directfb.org > http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev > _______________________________________________ directfb-dev mailing list directfb-dev@directfb.org http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev