00001 #define __NR_PIXBLOCK_C__
00002
00013 #include <cstring>
00014 #include <string>
00015 #include <string.h>
00016 #include <glib/gmem.h>
00017 #include "nr-pixblock.h"
00018
00020 #define NR_TINY_MAX sizeof (unsigned char *)
00021
00034 void
00035 nr_pixblock_setup_fast (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
00036 {
00037 int w, h, bpp;
00038 size_t size;
00039
00040 w = x1 - x0;
00041 h = y1 - y0;
00042 bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4;
00043
00044 size = bpp * w * h;
00045
00046 if (size <= NR_TINY_MAX) {
00047 pb->size = NR_PIXBLOCK_SIZE_TINY;
00048 if (clear) memset (pb->data.p, 0x0, size);
00049 } else if (size <= 4096) {
00050 pb->size = NR_PIXBLOCK_SIZE_4K;
00051 pb->data.px = nr_pixelstore_4K_new (clear, 0x0);
00052 } else if (size <= 16384) {
00053 pb->size = NR_PIXBLOCK_SIZE_16K;
00054 pb->data.px = nr_pixelstore_16K_new (clear, 0x0);
00055 } else if (size <= 65536) {
00056 pb->size = NR_PIXBLOCK_SIZE_64K;
00057 pb->data.px = nr_pixelstore_64K_new (clear, 0x0);
00058 } else if (size <= 262144) {
00059 pb->size = NR_PIXBLOCK_SIZE_256K;
00060 pb->data.px = nr_pixelstore_256K_new (clear, 0x0);
00061 } else if (size <= 1048576) {
00062 pb->size = NR_PIXBLOCK_SIZE_1M;
00063 pb->data.px = nr_pixelstore_1M_new (clear, 0x0);
00064 } else {
00065 pb->size = NR_PIXBLOCK_SIZE_BIG;
00066 pb->data.px = NULL;
00067 if (size > 100000000) {
00068
00069
00070 g_warning ("%lu bytes requested for pixel buffer, I won't try to allocate that.", (long unsigned) size);
00071 return;
00072 }
00073 pb->data.px = g_try_new (unsigned char, size);
00074 if (pb->data.px == NULL) {
00075 g_warning ("Could not allocate %lu bytes for pixel buffer!", (long unsigned) size);
00076 return;
00077 }
00078 if (clear) memset (pb->data.px, 0x0, size);
00079 }
00080
00081 pb->mode = mode;
00082 pb->empty = 1;
00083 pb->visible_area.x0 = pb->area.x0 = x0;
00084 pb->visible_area.y0 = pb->area.y0 = y0;
00085 pb->visible_area.x1 = pb->area.x1 = x1;
00086 pb->visible_area.y1 = pb->area.y1 = y1;
00087 pb->rs = bpp * w;
00088 }
00089
00100 void
00101 nr_pixblock_setup (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
00102 {
00103 int w, h, bpp;
00104 size_t size;
00105
00106 w = x1 - x0;
00107 h = y1 - y0;
00108 bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4;
00109
00110 size = bpp * w * h;
00111
00112 if (size <= NR_TINY_MAX) {
00113 pb->size = NR_PIXBLOCK_SIZE_TINY;
00114 if (clear) memset (pb->data.p, 0x0, size);
00115 } else {
00116 pb->size = NR_PIXBLOCK_SIZE_BIG;
00117 pb->data.px = g_new (unsigned char, size);
00118 if (clear) memset (pb->data.px, 0x0, size);
00119 }
00120
00121 pb->mode = mode;
00122 pb->empty = 1;
00123 pb->visible_area.x0 = pb->area.x0 = x0;
00124 pb->visible_area.y0 = pb->area.y0 = y0;
00125 pb->visible_area.x1 = pb->area.x1 = x1;
00126 pb->visible_area.y1 = pb->area.y1 = y1;
00127 pb->rs = bpp * w;
00128 }
00129
00139 void
00140 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)
00141 {
00142 int w, bpp;
00143
00144 w = x1 - x0;
00145 bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4;
00146
00147 pb->size = NR_PIXBLOCK_SIZE_STATIC;
00148 pb->mode = mode;
00149 pb->empty = empty;
00150 pb->visible_area.x0 = pb->area.x0 = x0;
00151 pb->visible_area.y0 = pb->area.y0 = y0;
00152 pb->visible_area.x1 = pb->area.x1 = x1;
00153 pb->visible_area.y1 = pb->area.y1 = y1;
00154 pb->data.px = px;
00155 pb->rs = rs;
00156
00157 g_assert (pb->data.px != NULL);
00158 if (clear) {
00159 if (rs == bpp * w) {
00162 if (pb->data.px)
00163 memset (pb->data.px, 0x0, bpp * (y1 - y0) * w);
00164 } else {
00165 int y;
00166 for (y = y0; y < y1; y++) {
00167 memset (pb->data.px + (y - y0) * rs, 0x0, bpp * w);
00168 }
00169 }
00170 }
00171 }
00172
00181 void
00182 nr_pixblock_release (NRPixBlock *pb)
00183 {
00184 switch (pb->size) {
00185 case NR_PIXBLOCK_SIZE_TINY:
00186 break;
00187 case NR_PIXBLOCK_SIZE_4K:
00188 nr_pixelstore_4K_free (pb->data.px);
00189 break;
00190 case NR_PIXBLOCK_SIZE_16K:
00191 nr_pixelstore_16K_free (pb->data.px);
00192 break;
00193 case NR_PIXBLOCK_SIZE_64K:
00194 nr_pixelstore_64K_free (pb->data.px);
00195 break;
00196 case NR_PIXBLOCK_SIZE_256K:
00197 nr_pixelstore_256K_free (pb->data.px);
00198 break;
00199 case NR_PIXBLOCK_SIZE_1M:
00200 nr_pixelstore_1M_free (pb->data.px);
00201 break;
00202 case NR_PIXBLOCK_SIZE_BIG:
00203 g_free (pb->data.px);
00204 break;
00205 case NR_PIXBLOCK_SIZE_STATIC:
00206 break;
00207 default:
00208 break;
00209 }
00210 }
00211
00219 NRPixBlock *
00220 nr_pixblock_new (NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
00221 {
00222 NRPixBlock *pb;
00223
00224 pb = g_new (NRPixBlock, 1);
00225 if (!pb) return 0;
00226
00227 nr_pixblock_setup (pb, mode, x0, y0, x1, y1, clear);
00228 if (pb->size!=NR_PIXBLOCK_SIZE_TINY && !pb->data.px) {
00229 g_free(pb);
00230 return 0;
00231 }
00232
00233 return pb;
00234 }
00235
00242 NRPixBlock *
00243 nr_pixblock_new_fast (NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear)
00244 {
00245 NRPixBlock *pb;
00246
00247 pb = g_new (NRPixBlock, 1);
00248 if (!pb) return 0;
00249
00250 nr_pixblock_setup_fast (pb, mode, x0, y0, x1, y1, clear);
00251 if (pb->size!=NR_PIXBLOCK_SIZE_TINY && !pb->data.px) {
00252 g_free(pb);
00253 return 0;
00254 }
00255
00256 return pb;
00257 }
00258
00264 NRPixBlock *
00265 nr_pixblock_free (NRPixBlock *pb)
00266 {
00267 nr_pixblock_release (pb);
00268
00269 g_free (pb);
00270
00271 return NULL;
00272 }
00273
00274
00275
00276 #define NR_4K_BLOCK 32
00277 static unsigned char **nr_4K_px = NULL;
00278 static unsigned int nr_4K_len = 0;
00279 static unsigned int nr_4K_size = 0;
00280
00281 unsigned char *
00282 nr_pixelstore_4K_new (bool clear, unsigned char val)
00283 {
00284 unsigned char *px;
00285
00286 if (nr_4K_len != 0) {
00287 nr_4K_len -= 1;
00288 px = nr_4K_px[nr_4K_len];
00289 } else {
00290 px = g_new (unsigned char, 4096);
00291 }
00292
00293 if (clear) memset (px, val, 4096);
00294
00295 return px;
00296 }
00297
00298 void
00299 nr_pixelstore_4K_free (unsigned char *px)
00300 {
00301 if (nr_4K_len == nr_4K_size) {
00302 nr_4K_size += NR_4K_BLOCK;
00303 nr_4K_px = g_renew (unsigned char *, nr_4K_px, nr_4K_size);
00304 }
00305
00306 nr_4K_px[nr_4K_len] = px;
00307 nr_4K_len += 1;
00308 }
00309
00310 #define NR_16K_BLOCK 32
00311 static unsigned char **nr_16K_px = NULL;
00312 static unsigned int nr_16K_len = 0;
00313 static unsigned int nr_16K_size = 0;
00314
00315 unsigned char *
00316 nr_pixelstore_16K_new (bool clear, unsigned char val)
00317 {
00318 unsigned char *px;
00319
00320 if (nr_16K_len != 0) {
00321 nr_16K_len -= 1;
00322 px = nr_16K_px[nr_16K_len];
00323 } else {
00324 px = g_new (unsigned char, 16384);
00325 }
00326
00327 if (clear) memset (px, val, 16384);
00328
00329 return px;
00330 }
00331
00332 void
00333 nr_pixelstore_16K_free (unsigned char *px)
00334 {
00335 if (nr_16K_len == nr_16K_size) {
00336 nr_16K_size += NR_16K_BLOCK;
00337 nr_16K_px = g_renew (unsigned char *, nr_16K_px, nr_16K_size);
00338 }
00339
00340 nr_16K_px[nr_16K_len] = px;
00341 nr_16K_len += 1;
00342 }
00343
00344 #define NR_64K_BLOCK 32
00345 static unsigned char **nr_64K_px = NULL;
00346 static unsigned int nr_64K_len = 0;
00347 static unsigned int nr_64K_size = 0;
00348
00349 unsigned char *
00350 nr_pixelstore_64K_new (bool clear, unsigned char val)
00351 {
00352 unsigned char *px;
00353
00354 if (nr_64K_len != 0) {
00355 nr_64K_len -= 1;
00356 px = nr_64K_px[nr_64K_len];
00357 } else {
00358 px = g_new (unsigned char, 65536);
00359 }
00360
00361 if (clear) memset (px, val, 65536);
00362
00363 return px;
00364 }
00365
00366 void
00367 nr_pixelstore_64K_free (unsigned char *px)
00368 {
00369 if (nr_64K_len == nr_64K_size) {
00370 nr_64K_size += NR_64K_BLOCK;
00371 nr_64K_px = g_renew (unsigned char *, nr_64K_px, nr_64K_size);
00372 }
00373
00374 nr_64K_px[nr_64K_len] = px;
00375 nr_64K_len += 1;
00376 }
00377
00378 #define NR_256K_BLOCK 32
00379 #define NR_256K 262144
00380 static unsigned char **nr_256K_px = NULL;
00381 static unsigned int nr_256K_len = 0;
00382 static unsigned int nr_256K_size = 0;
00383
00384 unsigned char *
00385 nr_pixelstore_256K_new (bool clear, unsigned char val)
00386 {
00387 unsigned char *px;
00388
00389 if (nr_256K_len != 0) {
00390 nr_256K_len -= 1;
00391 px = nr_256K_px[nr_256K_len];
00392 } else {
00393 px = g_new (unsigned char, NR_256K);
00394 }
00395
00396 if (clear) memset (px, val, NR_256K);
00397
00398 return px;
00399 }
00400
00401 void
00402 nr_pixelstore_256K_free (unsigned char *px)
00403 {
00404 if (nr_256K_len == nr_256K_size) {
00405 nr_256K_size += NR_256K_BLOCK;
00406 nr_256K_px = g_renew (unsigned char *, nr_256K_px, nr_256K_size);
00407 }
00408
00409 nr_256K_px[nr_256K_len] = px;
00410 nr_256K_len += 1;
00411 }
00412
00413 #define NR_1M_BLOCK 32
00414 #define NR_1M 1048576
00415 static unsigned char **nr_1M_px = NULL;
00416 static unsigned int nr_1M_len = 0;
00417 static unsigned int nr_1M_size = 0;
00418
00419 unsigned char *
00420 nr_pixelstore_1M_new (bool clear, unsigned char val)
00421 {
00422 unsigned char *px;
00423
00424 if (nr_1M_len != 0) {
00425 nr_1M_len -= 1;
00426 px = nr_1M_px[nr_1M_len];
00427 } else {
00428 px = g_new (unsigned char, NR_1M);
00429 }
00430
00431 if (clear) memset (px, val, NR_1M);
00432
00433 return px;
00434 }
00435
00436 void
00437 nr_pixelstore_1M_free (unsigned char *px)
00438 {
00439 if (nr_1M_len == nr_1M_size) {
00440 nr_1M_size += NR_1M_BLOCK;
00441 nr_1M_px = g_renew (unsigned char *, nr_1M_px, nr_1M_size);
00442 }
00443
00444 nr_1M_px[nr_1M_len] = px;
00445 nr_1M_len += 1;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457