logo

Inkscape

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files

nr-pixblock.cpp

Go to the documentation of this file.
00001 #define __NR_PIXBLOCK_C__
00002 
00012 #include <cstring>
00013 #include <string>
00014 #include <string.h>
00015 #include <glib/gmem.h>
00016 #include "nr-pixblock.h"
00017 
00019 #define NR_TINY_MAX sizeof (unsigned char *)
00020 
00033 void
00034 nr_pixblock_setup_fast (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
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 }
00088 
00099 void
00100 nr_pixblock_setup (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
00101 {
00102     int w, h, bpp;
00103     size_t size;
00104 
00105     w = x1 - x0;
00106     h = y1 - y0;
00107     bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4;
00108 
00109     size = bpp * w * h;
00110 
00111     if (size <= NR_TINY_MAX) {
00112         pb->size = NR_PIXBLOCK_SIZE_TINY;
00113         if (clear) memset (pb->data.p, 0x0, size);
00114     } else {
00115         pb->size = NR_PIXBLOCK_SIZE_BIG;
00116         pb->data.px = g_new (unsigned char, size);
00117         if (clear) memset (pb->data.px, 0x0, size);
00118     }
00119 
00120     pb->mode = mode;
00121     pb->empty = 1;
00122     pb->visible_area.x0 = pb->area.x0 = x0;
00123     pb->visible_area.y0 = pb->area.y0 = y0;
00124     pb->visible_area.x1 = pb->area.x1 = x1;
00125     pb->visible_area.y1 = pb->area.y1 = y1;
00126     pb->rs = bpp * w;
00127 }
00128 
00138 void
00139 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)
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 }
00171 
00180 void
00181 nr_pixblock_release (NRPixBlock *pb)
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 }
00210 
00218 NRPixBlock *
00219 nr_pixblock_new (NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
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 }
00229 
00235 NRPixBlock *
00236 nr_pixblock_free (NRPixBlock *pb)
00237 {
00238     nr_pixblock_release (pb);
00239 
00240     g_free (pb);
00241 
00242     return NULL;
00243 }
00244 
00245 /* PixelStore operations */
00246 
00247 #define NR_4K_BLOCK 32
00248 static unsigned char **nr_4K_px = NULL;
00249 static unsigned int nr_4K_len = 0;
00250 static unsigned int nr_4K_size = 0;
00251 
00252 unsigned char *
00253 nr_pixelstore_4K_new (bool clear, unsigned char val)
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 }
00268 
00269 void
00270 nr_pixelstore_4K_free (unsigned char *px)
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 }
00280 
00281 #define NR_16K_BLOCK 32
00282 static unsigned char **nr_16K_px = NULL;
00283 static unsigned int nr_16K_len = 0;
00284 static unsigned int nr_16K_size = 0;
00285 
00286 unsigned char *
00287 nr_pixelstore_16K_new (bool clear, unsigned char val)
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 }
00302 
00303 void
00304 nr_pixelstore_16K_free (unsigned char *px)
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 }
00314 
00315 #define NR_64K_BLOCK 32
00316 static unsigned char **nr_64K_px = NULL;
00317 static unsigned int nr_64K_len = 0;
00318 static unsigned int nr_64K_size = 0;
00319 
00320 unsigned char *
00321 nr_pixelstore_64K_new (bool clear, unsigned char val)
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 }
00336 
00337 void
00338 nr_pixelstore_64K_free (unsigned char *px)
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 }
00348 
00349 #define NR_256K_BLOCK 32
00350 #define NR_256K 262144
00351 static unsigned char **nr_256K_px = NULL;
00352 static unsigned int nr_256K_len = 0;
00353 static unsigned int nr_256K_size = 0;
00354 
00355 unsigned char *
00356 nr_pixelstore_256K_new (bool clear, unsigned char val)
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 }
00371 
00372 void
00373 nr_pixelstore_256K_free (unsigned char *px)
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 }
00383 
00384 #define NR_1M_BLOCK 32
00385 #define NR_1M 1048576
00386 static unsigned char **nr_1M_px = NULL;
00387 static unsigned int nr_1M_len = 0;
00388 static unsigned int nr_1M_size = 0;
00389 
00390 unsigned char *
00391 nr_pixelstore_1M_new (bool clear, unsigned char val)
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 }
00406 
00407 void
00408 nr_pixelstore_1M_free (unsigned char *px)
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 }
00418 
00419 /*
00420   Local Variables:
00421   mode:c++
00422   c-file-style:"stroustrup"
00423   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
00424   indent-tabs-mode:nil
00425   fill-column:99
00426   End:
00427 */
00428 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :