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) {
00067
00068
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) {
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
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
00421
00422
00423
00424
00425
00426
00427
00428