nr-pixblock.h File Reference

Pixel block structure. More...

Go to the source code of this file.


Classes

struct  NRPixBlock
 The pixel block struct. More...

Enumerations

enum  NR_PIXBLOCK_SIZE {
  NR_PIXBLOCK_SIZE_TINY, NR_PIXBLOCK_SIZE_4K, NR_PIXBLOCK_SIZE_16K, NR_PIXBLOCK_SIZE_64K,
  NR_PIXBLOCK_SIZE_256K, NR_PIXBLOCK_SIZE_1M, NR_PIXBLOCK_SIZE_BIG, NR_PIXBLOCK_SIZE_STATIC
}
 Size indicator. Hardcoded to max. 3 bits. More...
enum  NR_PIXBLOCK_MODE { NR_PIXBLOCK_MODE_A8, NR_PIXBLOCK_MODE_R8G8B8, NR_PIXBLOCK_MODE_R8G8B8A8N, NR_PIXBLOCK_MODE_R8G8B8A8P }
 Mode indicator. Hardcoded to max. 2 bits. More...

Functions

void nr_pixblock_setup_fast (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
 Returns number of bytes per pixel (1, 3, or 4).
void nr_pixblock_setup_extern (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, unsigned char *px, int rs, bool empty, bool clear)
 Pixbuf initialisation with preset values.
void nr_pixblock_release (NRPixBlock *pb)
 Frees memory taken by pixel data in NRPixBlock.
NRPixBlocknr_pixblock_new (NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
 Allocates NRPixBlock and sets it up.
NRPixBlocknr_pixblock_free (NRPixBlock *pb)
 Frees all memory taken by pixblock.
unsigned char * nr_pixelstore_4K_new (bool clear, unsigned char val)
void nr_pixelstore_4K_free (unsigned char *px)
unsigned char * nr_pixelstore_16K_new (bool clear, unsigned char val)
void nr_pixelstore_16K_free (unsigned char *px)
unsigned char * nr_pixelstore_64K_new (bool clear, unsigned char val)
void nr_pixelstore_64K_free (unsigned char *px)
unsigned char * nr_pixelstore_256K_new (bool clear, unsigned char val)
void nr_pixelstore_256K_free (unsigned char *px)
unsigned char * nr_pixelstore_1M_new (bool clear, unsigned char val)
void nr_pixelstore_1M_free (unsigned char *px)

Detailed Description

Pixel block structure.

Used for low-level rendering.

Authors: (C) 1999-2002 Lauris Kaplinski <lauris@kaplinski.com> (C) 2005 Ralf Stephan <ralf@ark.in-berlin.de> (some cleanup)

This code is in the Public Domain.

Definition in file nr-pixblock.h.


Enumeration Type Documentation

Mode indicator. Hardcoded to max. 2 bits.

Enumerator:
NR_PIXBLOCK_MODE_A8  Grayscale.
NR_PIXBLOCK_MODE_R8G8B8  8 bit RGB
NR_PIXBLOCK_MODE_R8G8B8A8N  Normal 8 bit RGBA.
NR_PIXBLOCK_MODE_R8G8B8A8P  Premultiplied 8 bit RGBA.

Definition at line 30 of file nr-pixblock.h.

Size indicator. Hardcoded to max. 3 bits.

Enumerator:
NR_PIXBLOCK_SIZE_TINY  Fits in (unsigned char *).
NR_PIXBLOCK_SIZE_4K  Pixelstore.
NR_PIXBLOCK_SIZE_16K  Pixelstore.
NR_PIXBLOCK_SIZE_64K  Pixelstore.
NR_PIXBLOCK_SIZE_256K  Pixelstore.
NR_PIXBLOCK_SIZE_1M  Pixelstore.
NR_PIXBLOCK_SIZE_BIG  Normally allocated.
NR_PIXBLOCK_SIZE_STATIC  Externally managed.

Definition at line 18 of file nr-pixblock.h.


Function Documentation

NRPixBlock* nr_pixblock_free ( NRPixBlock pb  ) 

Frees all memory taken by pixblock.

Returns:
NULL

Definition at line 236 of file nr-pixblock.cpp.

References nr_pixblock_release(), and NULL.

00237 {
00238     nr_pixblock_release (pb);
00239 
00240     g_free (pb);
00241 
00242     return NULL;
00243 }

NRPixBlock* nr_pixblock_new ( NR_PIXBLOCK_MODE  mode,
int  x0,
int  y0,
int  x1,
int  y1,
bool  clear 
)

Allocates NRPixBlock and sets it up.

Returns:
Pointer to fresh pixblock. Calls g_new() and nr_pixblock_setup(). FIXME: currently unused, delete?

Definition at line 219 of file nr-pixblock.cpp.

References nr_pixblock_setup().

00220 {
00221     NRPixBlock *pb;
00222 
00223     pb = g_new (NRPixBlock, 1);
00224 
00225     nr_pixblock_setup (pb, mode, x0, y0, x1, y1, clear);
00226 
00227     return pb;
00228 }

void nr_pixblock_release ( NRPixBlock pb  ) 

Frees memory taken by pixel data in NRPixBlock.

Parameters:
pb Pointer to pixblock.
Precondition:
pb and pb->data.px point to valid addresses.
According to pb->size, one of the functions for freeing the pixelstore is called. May be called regardless of how pixbuf was set up.

Definition at line 181 of file nr-pixblock.cpp.

References NRPixBlock::data, NR_PIXBLOCK_SIZE_16K, NR_PIXBLOCK_SIZE_1M, NR_PIXBLOCK_SIZE_256K, NR_PIXBLOCK_SIZE_4K, NR_PIXBLOCK_SIZE_64K, NR_PIXBLOCK_SIZE_BIG, NR_PIXBLOCK_SIZE_STATIC, NR_PIXBLOCK_SIZE_TINY, nr_pixelstore_16K_free(), nr_pixelstore_1M_free(), nr_pixelstore_256K_free(), nr_pixelstore_4K_free(), nr_pixelstore_64K_free(), NRPixBlock::px, and NRPixBlock::size.

Referenced by clonetiler_trace_pick(), Inkscape::Extension::Internal::PrintWin32::finish(), nr_arena_glyphs_group_render(), nr_arena_item_invoke_render(), nr_arena_render_paintserver_fill(), nr_arena_shape_clip(), nr_arena_shape_render(), nr_gdk_draw_gray_garbage(), nr_gdk_draw_rgba32_solid(), nr_pixblock_draw_line_rgba32(), nr_pixblock_free(), NR::FilterMorphology::render(), NR::FilterMerge::render(), NR::FilterImage::render(), NR::FilterGaussian::render(), NR::FilterDisplacementMap::render(), NR::FilterComposite::render(), NR::FilterComponentTransfer::render(), NR::FilterColorMatrix::render(), NR::FilterBlend::render(), render_pixbuf(), sp_canvas_arena_render(), sp_canvas_paint_single_buffer(), sp_dropper_context_root_handler(), sp_export_get_rows(), sp_flood_do_flood_fill(), sp_font_preview_expose(), sp_gradient_image_update(), sp_icon_doc_icon(), sp_pat_fill(), sp_pattern_painter_free(), NR::transform_nearest(), NR::FilterTurbulence::update_pixbuffer(), and NR::FilterTurbulence::~FilterTurbulence().

00182 {
00183     switch (pb->size) {
00184     case NR_PIXBLOCK_SIZE_TINY:
00185         break;
00186     case NR_PIXBLOCK_SIZE_4K:
00187         nr_pixelstore_4K_free (pb->data.px);
00188         break;
00189     case NR_PIXBLOCK_SIZE_16K:
00190         nr_pixelstore_16K_free (pb->data.px);
00191         break;
00192     case NR_PIXBLOCK_SIZE_64K:
00193         nr_pixelstore_64K_free (pb->data.px);
00194         break;
00195     case NR_PIXBLOCK_SIZE_256K:
00196         nr_pixelstore_256K_free (pb->data.px);
00197         break;
00198     case NR_PIXBLOCK_SIZE_1M:
00199         nr_pixelstore_1M_free (pb->data.px);
00200         break;
00201     case NR_PIXBLOCK_SIZE_BIG:
00202         g_free (pb->data.px);
00203         break;
00204     case NR_PIXBLOCK_SIZE_STATIC:
00205         break;
00206     default:
00207         break;
00208     }
00209 }

void nr_pixblock_setup_extern ( NRPixBlock pb,
NR_PIXBLOCK_MODE  mode,
int  x0,
int  y0,
int  x1,
int  y1,
unsigned char *  px,
int  rs,
bool  empty,
bool  clear 
)

Pixbuf initialisation with preset values.

After copying all parameters into the NRPixBlock struct, the pixel buffer is cleared if the clear flag is set.

Parameters:
pb Pointer to the pixbuf struct.
mode Indicates grayscale/RGB/RGBA.
clear True if buffer should be cleared.
Precondition:
x1>=x0 && y1>=y0 && pb!=NULL

Todo:
How do you recognise if

px was an uncleared tiny buffer?

Definition at line 139 of file nr-pixblock.cpp.

References NRPixBlock::area, bpp, NRPixBlock::data, NRPixBlock::empty, NRPixBlock::mode, NR_PIXBLOCK_MODE_A8, NR_PIXBLOCK_MODE_R8G8B8, NR_PIXBLOCK_SIZE_STATIC, NULL, NRPixBlock::px, NRPixBlock::rs, NRPixBlock::size, NRPixBlock::visible_area, w, NRRectL::x0, NRRectL::x1, y, NRRectL::y0, and NRRectL::y1.

Referenced by clonetiler_trace_pick(), Inkscape::Extension::Internal::PrintWin32::finish(), Inkscape::Extension::Internal::PrintPS::finish(), nr_arena_item_invoke_render(), NR::FilterImage::render(), render_pixbuf(), sp_canvas_arena_render(), sp_canvas_paint_single_buffer(), sp_export_get_rows(), sp_flood_do_flood_fill(), sp_font_preview_expose(), sp_generate_internal_bitmap(), sp_gradient_image_update(), sp_icon_doc_icon(), and sp_pat_fill().

00140 {
00141     int w, bpp;
00142 
00143     w = x1 - x0;
00144     bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4;
00145 
00146     pb->size = NR_PIXBLOCK_SIZE_STATIC; 
00147     pb->mode = mode;
00148     pb->empty = empty;
00149     pb->visible_area.x0 = pb->area.x0 = x0;
00150     pb->visible_area.y0 = pb->area.y0 = y0;
00151     pb->visible_area.x1 = pb->area.x1 = x1;
00152     pb->visible_area.y1 = pb->area.y1 = y1;
00153     pb->data.px = px;
00154     pb->rs = rs;
00155 
00156         g_assert (pb->data.px != NULL);
00157     if (clear) {
00158         if (rs == bpp * w) {
00161             if (pb->data.px) 
00162                 memset (pb->data.px, 0x0, bpp * (y1 - y0) * w);
00163         } else {
00164             int y;
00165             for (y = y0; y < y1; y++) {
00166                 memset (pb->data.px + (y - y0) * rs, 0x0, bpp * w);
00167             }
00168         }
00169     }
00170 }

void nr_pixblock_setup_fast ( NRPixBlock pb,
NR_PIXBLOCK_MODE  mode,
int  x0,
int  y0,
int  x1,
int  y1,
bool  clear 
) [inline]

Returns number of bytes per pixel (1, 3, or 4).

Returns number of bytes per pixel (1, 3, or 4).

Pixbuf sizes are differentiated into tiny, <4K, <16K, <64K, and more, with each type having its own method of memory handling. After allocating memory, the buffer is cleared if the clear flag is set. Intended to reduce memory fragmentation.

Parameters:
pb Pointer to the pixbuf struct.
mode Indicates grayscale/RGB/RGBA.
clear True if buffer should be cleared.
Precondition:
x1>=x0 && y1>=y0 && pb!=NULL

Definition at line 34 of file nr-pixblock.cpp.

References NRPixBlock::area, bpp, NRPixBlock::data, NRPixBlock::empty, h, NRPixBlock::mode, NR_PIXBLOCK_MODE_A8, NR_PIXBLOCK_MODE_R8G8B8, NR_PIXBLOCK_SIZE_16K, NR_PIXBLOCK_SIZE_1M, NR_PIXBLOCK_SIZE_256K, NR_PIXBLOCK_SIZE_4K, NR_PIXBLOCK_SIZE_64K, NR_PIXBLOCK_SIZE_BIG, NR_PIXBLOCK_SIZE_TINY, nr_pixelstore_16K_new(), nr_pixelstore_1M_new(), nr_pixelstore_256K_new(), nr_pixelstore_4K_new(), nr_pixelstore_64K_new(), NR_TINY_MAX, NULL, NRPixBlock::p, NRPixBlock::px, NRPixBlock::rs, NRPixBlock::size, NRPixBlock::visible_area, w, NRRectL::x0, NRRectL::x1, NRRectL::y0, and NRRectL::y1.

Referenced by NR::filter_get_alpha(), main(), nr_arena_glyphs_group_render(), nr_arena_item_get_background(), nr_arena_item_invoke_render(), nr_arena_render_paintserver_fill(), nr_arena_shape_clip(), nr_arena_shape_render(), nr_gdk_draw_gray_garbage(), nr_gdk_draw_rgba32_solid(), nr_pixblock_draw_line_rgba32(), NR::Filter::render(), NR::FilterTurbulence::render(), NR::FilterTile::render(), NR::FilterSpecularLighting::render(), NR::FilterOffset::render(), NR::FilterMorphology::render(), NR::FilterMerge::render(), NR::FilterImage::render(), NR::FilterGaussian::render(), NR::FilterFlood::render(), NR::FilterDisplacementMap::render(), NR::FilterDiffuseLighting::render(), NR::FilterConvolveMatrix::render(), NR::FilterComposite::render(), NR::FilterComponentTransfer::render(), NR::FilterColorMatrix::render(), NR::FilterBlend::render(), sp_canvas_paint_single_buffer(), sp_dropper_context_root_handler(), sp_dyna_draw_brush(), sp_font_preview_expose(), NR::transform_nearest(), and NR::FilterTurbulence::update_pixbuffer().

00035 {
00036     int w, h, bpp;
00037     size_t size;
00038 
00039     w = x1 - x0;
00040     h = y1 - y0;
00041     bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4;
00042 
00043     size = bpp * w * h;
00044 
00045     if (size <= NR_TINY_MAX) {
00046         pb->size = NR_PIXBLOCK_SIZE_TINY;
00047         if (clear) memset (pb->data.p, 0x0, size);
00048     } else if (size <= 4096) {
00049         pb->size = NR_PIXBLOCK_SIZE_4K;
00050         pb->data.px = nr_pixelstore_4K_new (clear, 0x0);
00051     } else if (size <= 16384) {
00052         pb->size = NR_PIXBLOCK_SIZE_16K;
00053         pb->data.px = nr_pixelstore_16K_new (clear, 0x0);
00054     } else if (size <= 65536) {
00055         pb->size = NR_PIXBLOCK_SIZE_64K;
00056         pb->data.px = nr_pixelstore_64K_new (clear, 0x0);
00057     } else if (size <= 262144) {
00058         pb->size = NR_PIXBLOCK_SIZE_256K;
00059         pb->data.px = nr_pixelstore_256K_new (clear, 0x0);
00060     } else if (size <= 1048576) {
00061         pb->size = NR_PIXBLOCK_SIZE_1M;
00062         pb->data.px = nr_pixelstore_1M_new (clear, 0x0);
00063     } else {
00064         pb->size = NR_PIXBLOCK_SIZE_BIG;
00065              pb->data.px = NULL;
00066         if (size > 100000000) { // Don't even try to allocate more than 100Mb (5000x5000 RGBA
00067                             // pixels). It'll just bog the system down even if successful. FIXME:
00068                             // Can anyone suggest something better than the magic number?
00069                 g_warning ("%lu bytes requested for pixel buffer, I won't try to allocate that.", (long unsigned) size);
00070                 return;
00071              }
00072         pb->data.px = g_try_new (unsigned char, size);
00073         if (pb->data.px == NULL) { // memory allocation failed
00074                 g_warning ("Could not allocate %lu bytes for pixel buffer!", (long unsigned) size);
00075                 return;
00076              }
00077         if (clear) memset (pb->data.px, 0x0, size);
00078     }
00079 
00080     pb->mode = mode;
00081     pb->empty = 1;
00082     pb->visible_area.x0 = pb->area.x0 = x0;
00083     pb->visible_area.y0 = pb->area.y0 = y0;
00084     pb->visible_area.x1 = pb->area.x1 = x1;
00085     pb->visible_area.y1 = pb->area.y1 = y1;
00086     pb->rs = bpp * w;
00087 }

void nr_pixelstore_16K_free ( unsigned char *  px  ) 

Definition at line 304 of file nr-pixblock.cpp.

References NR_16K_BLOCK, nr_16K_len, nr_16K_px, and nr_16K_size.

Referenced by nr_pixblock_release(), and sp_font_preview_expose().

00305 {
00306     if (nr_16K_len == nr_16K_size) {
00307         nr_16K_size += NR_16K_BLOCK;
00308         nr_16K_px = g_renew (unsigned char *, nr_16K_px, nr_16K_size);
00309     }
00310 
00311     nr_16K_px[nr_16K_len] = px;
00312     nr_16K_len += 1;
00313 }

unsigned char* nr_pixelstore_16K_new ( bool  clear,
unsigned char  val 
)

Definition at line 287 of file nr-pixblock.cpp.

References nr_16K_len, and nr_16K_px.

Referenced by nr_pixblock_setup_fast(), and sp_font_preview_expose().

00288 {
00289     unsigned char *px;
00290 
00291     if (nr_16K_len != 0) {
00292         nr_16K_len -= 1;
00293         px = nr_16K_px[nr_16K_len];
00294     } else {
00295         px = g_new (unsigned char, 16384);
00296     }
00297     
00298     if (clear) memset (px, val, 16384);
00299 
00300     return px;
00301 }

void nr_pixelstore_1M_free ( unsigned char *  px  ) 

Definition at line 408 of file nr-pixblock.cpp.

References NR_1M_BLOCK, nr_1M_len, nr_1M_px, and nr_1M_size.

Referenced by nr_pixblock_release(), and sp_canvas_paint_single_buffer().

00409 {
00410     if (nr_1M_len == nr_1M_size) {
00411         nr_1M_size += NR_1M_BLOCK;
00412         nr_1M_px = g_renew (unsigned char *, nr_1M_px, nr_1M_size);
00413     }
00414 
00415     nr_1M_px[nr_1M_len] = px;
00416     nr_1M_len += 1;
00417 }

unsigned char* nr_pixelstore_1M_new ( bool  clear,
unsigned char  val 
)

Definition at line 391 of file nr-pixblock.cpp.

References NR_1M, nr_1M_len, and nr_1M_px.

Referenced by nr_pixblock_setup_fast(), and sp_canvas_paint_single_buffer().

00392 {
00393     unsigned char *px;
00394 
00395     if (nr_1M_len != 0) {
00396         nr_1M_len -= 1;
00397         px = nr_1M_px[nr_1M_len];
00398     } else {
00399            px = g_new (unsigned char, NR_1M);
00400     }
00401 
00402     if (clear) memset (px, val, NR_1M);
00403 
00404     return px;
00405 }

void nr_pixelstore_256K_free ( unsigned char *  px  ) 

Definition at line 373 of file nr-pixblock.cpp.

References NR_256K_BLOCK, nr_256K_len, nr_256K_px, and nr_256K_size.

Referenced by nr_pixblock_release(), and sp_canvas_paint_single_buffer().

00374 {
00375     if (nr_256K_len == nr_256K_size) {
00376         nr_256K_size += NR_256K_BLOCK;
00377         nr_256K_px = g_renew (unsigned char *, nr_256K_px, nr_256K_size);
00378     }
00379 
00380     nr_256K_px[nr_256K_len] = px;
00381     nr_256K_len += 1;
00382 }

unsigned char* nr_pixelstore_256K_new ( bool  clear,
unsigned char  val 
)

Definition at line 356 of file nr-pixblock.cpp.

References NR_256K, nr_256K_len, and nr_256K_px.

Referenced by nr_pixblock_setup_fast(), and sp_canvas_paint_single_buffer().

00357 {
00358     unsigned char *px;
00359 
00360     if (nr_256K_len != 0) {
00361         nr_256K_len -= 1;
00362         px = nr_256K_px[nr_256K_len];
00363     } else {
00364            px = g_new (unsigned char, NR_256K);
00365     }
00366 
00367     if (clear) memset (px, val, NR_256K);
00368 
00369     return px;
00370 }

void nr_pixelstore_4K_free ( unsigned char *  px  ) 

Definition at line 270 of file nr-pixblock.cpp.

References NR_4K_BLOCK, nr_4K_len, nr_4K_px, and nr_4K_size.

Referenced by nr_pixblock_release().

00271 {
00272     if (nr_4K_len == nr_4K_size) {
00273         nr_4K_size += NR_4K_BLOCK;
00274         nr_4K_px = g_renew (unsigned char *, nr_4K_px, nr_4K_size);
00275     }
00276 
00277     nr_4K_px[nr_4K_len] = px;
00278     nr_4K_len += 1;
00279 }

unsigned char* nr_pixelstore_4K_new ( bool  clear,
unsigned char  val 
)

Definition at line 253 of file nr-pixblock.cpp.

References nr_4K_len, and nr_4K_px.

Referenced by nr_pixblock_setup_fast().

00254 {
00255     unsigned char *px;
00256 
00257     if (nr_4K_len != 0) {
00258         nr_4K_len -= 1;
00259         px = nr_4K_px[nr_4K_len];
00260     } else {
00261         px = g_new (unsigned char, 4096);
00262     }
00263     
00264     if (clear) memset (px, val, 4096);
00265 
00266     return px;
00267 }

void nr_pixelstore_64K_free ( unsigned char *  px  ) 

Definition at line 338 of file nr-pixblock.cpp.

References NR_64K_BLOCK, nr_64K_len, nr_64K_px, and nr_64K_size.

Referenced by nr_pixblock_release(), and sp_export_png_file().

00339 {
00340     if (nr_64K_len == nr_64K_size) {
00341         nr_64K_size += NR_64K_BLOCK;
00342         nr_64K_px = g_renew (unsigned char *, nr_64K_px, nr_64K_size);
00343     }
00344 
00345     nr_64K_px[nr_64K_len] = px;
00346     nr_64K_len += 1;
00347 }

unsigned char* nr_pixelstore_64K_new ( bool  clear,
unsigned char  val 
)

Definition at line 321 of file nr-pixblock.cpp.

References nr_64K_len, and nr_64K_px.

Referenced by nr_pixblock_setup_fast(), and sp_export_png_file().

00322 {
00323     unsigned char *px;
00324 
00325     if (nr_64K_len != 0) {
00326         nr_64K_len -= 1;
00327         px = nr_64K_px[nr_64K_len];
00328     } else {
00329         px = g_new (unsigned char, 65536);
00330     }
00331 
00332     if (clear) memset (px, val, 65536);
00333 
00334     return px;
00335 }