00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "imagetile.h"
00018 #include <lib/salloc.h>
00019
00020
00021
00022 static const flt CF_R5 = 0.03225806451612903f;
00023 static const flt CF_R6 = 0.01587301587301587f;
00024 static const flt CF_R8 = 0.003921568627450980f;
00025 static const flt CF_R16 = 0.00001525902189669642f;
00026 static const flt CF_N5 = 31.0f;
00027 static const flt CF_N6 = 63.0f;
00028 static const flt CF_N8 = 255.0f;
00029 static const flt CF_N16 = 65565.0f;
00030
00031
00032 static inline flt P2F(uint8 x) { return(CF_R8*x); }
00033 static inline flt P2F(uint16 x) { return(CF_R16*x); }
00034
00035 static inline uint8 F2P8(flt x) { return((uint8)(CF_N8*x+0.5f)); }
00036 static inline uint16 F2P16(flt x) { return((uint16)(CF_N16*x+0.5f)); }
00037
00038
00039 static inline flt P2F_5(uint16 x) { return(CF_R5*x); }
00040 static inline flt P2F_6(uint16 x) { return(CF_R6*x); }
00041 static inline uint16 F2P_5(flt x) { return((uint16)(CF_N5*x+0.5f)); }
00042 static inline uint16 F2P_6(flt x) { return((uint16)(CF_N6*x+0.5f)); }
00043
00044
00045
00046 template<typename D,typename S>static inline void CV_GET(D*,S);
00047 template<typename D,typename S>static inline void CV_PUT(D*,S);
00048
00049 static inline void CV_GET(uint8 *d,uint8 s) { *d=s; }
00050
00051 static inline void CV_GET(uint16 *d,uint8 s) { *d=s; }
00052 static inline void CV_GET(uint16 *d,uint16 s) { *d=s; }
00053
00054 static inline void CV_PUT(uint8 *d,uint8 s) { *d=s; }
00055 static inline void CV_PUT(uint8 *d,uint16 s) { *d=s; }
00056 static inline void CV_PUT(uint16 *d,uint8 s) { *d=s; }
00057 static inline void CV_PUT(uint16 *d,uint16 s) { *d=s; }
00058
00059 static inline void CV_GET(flt *d,flt s) { *d=s; }
00060 static inline void CV_PUT(flt *d,flt s) { *d=s; }
00061
00062 static inline void CV_GET(flt *d,uint8 s) { *d=P2F(s); }
00063 static inline void CV_GET(flt *d,uint16 s) { *d=P2F(s); }
00064
00065 static inline void CV_PUT(uint8 *d,flt s) { *d=F2P8(s); }
00066 static inline void CV_PUT(uint16 *d,flt s) { *d=F2P16(s); }
00067
00068
00069
00070 struct PixmapImageTileInternal
00071 {
00072
00073
00074 static void no_getpixel8(const PixmapImageTile *,uint,uint,uint8 *)
00075 { CritAssert(!"unimplemented"); }
00076 static void no_getpixel16(const PixmapImageTile *,uint,uint,uint16 *)
00077 { CritAssert(!"unimplemented"); }
00078 static void no_getpixelF(const PixmapImageTile *,uint,uint,flt *)
00079 { CritAssert(!"unimplemented"); }
00080 static void no_putpixel8(PixmapImageTile *,uint,uint,const uint8 *)
00081 { CritAssert(!"unimplemented"); }
00082 static void no_putpixel16(PixmapImageTile *,uint,uint,const uint16 *)
00083 { CritAssert(!"unimplemented"); }
00084 static void no_putpixelF(PixmapImageTile *,uint,uint,const flt *)
00085 { CritAssert(!"unimplemented"); }
00086
00087
00088
00089
00090
00091
00092 template<typename C,typename P>static void getpixel_1(
00093 const PixmapImageTile *t,uint x,uint y,P *p)
00094 {
00095 CV_GET( p, ((const C*)t->data)[y*t->w+x] );
00096 }
00097 template<typename C,typename P>static void putpixel_1(
00098 PixmapImageTile *t,uint x,uint y,const P *p)
00099 {
00100 CV_PUT( &((C*)t->data)[y*t->w+x], *p );
00101 }
00102
00103
00104 template<typename C,typename P>static void getpixel_2(
00105 const PixmapImageTile *t,uint x,uint y,P *p)
00106 {
00107 const C *v = &((const C*)t->data)[(y*t->w+x)*2];
00108 CV_GET( p++, *v++ );
00109 CV_GET( p, *v );
00110 }
00111 template<typename C,typename P>static void putpixel_2(
00112 PixmapImageTile *t,uint x,uint y,const P *p)
00113 {
00114 C *v = &((C*)t->data)[(y*t->w+x)*2];
00115 CV_PUT( v++, *p++ );
00116 CV_PUT( v, *p );
00117 }
00118
00119
00120 template<typename C,typename P>static void getpixel_3(
00121 const PixmapImageTile *t,uint x,uint y,P *p)
00122 {
00123 const C *v = &((const C*)t->data)[(y*t->w+x)*3];
00124 CV_GET( p++, *v++ );
00125 CV_GET( p++, *v++ );
00126 CV_GET( p, *v );
00127 }
00128 template<typename C,typename P>static void putpixel_3(
00129 PixmapImageTile *t,uint x,uint y,const P *p)
00130 {
00131 C *v = &((C*)t->data)[(y*t->w+x)*3];
00132 CV_PUT( v++, *p++ );
00133 CV_PUT( v++, *p++ );
00134 CV_PUT( v, *p );
00135 }
00136
00137
00138 template<typename C,typename P>static void getpixel_4(
00139 const PixmapImageTile *t,uint x,uint y,P *p)
00140 {
00141 const C *v = &((const C*)t->data)[(y*t->w+x)*4];
00142 CV_GET( p++, *v++ );
00143 CV_GET( p++, *v++ );
00144 CV_GET( p++, *v++ );
00145 CV_GET( p, *v );
00146 }
00147 template<typename C,typename P>static void putpixel_4(
00148 PixmapImageTile *t,uint x,uint y,const P *p)
00149 {
00150 C *v = &((C*)t->data)[(y*t->w+x)*4];
00151 CV_PUT( v++, *p++ );
00152 CV_PUT( v++, *p++ );
00153 CV_PUT( v++, *p++ );
00154 CV_PUT( v, *p );
00155 }
00156
00157
00158 template<typename C,typename P>static void getpixel_5(
00159 const PixmapImageTile *t,uint x,uint y,P *p)
00160 {
00161 const C *v = &((const C*)t->data)[(y*t->w+x)*5];
00162 CV_GET( p++, *v++ );
00163 CV_GET( p++, *v++ );
00164 CV_GET( p++, *v++ );
00165 CV_GET( p++, *v++ );
00166 CV_GET( p, *v );
00167 }
00168 template<typename C,typename P>static void putpixel_5(
00169 PixmapImageTile *t,uint x,uint y,const P *p)
00170 {
00171 C *v = &((C*)t->data)[(y*t->w+x)*5];
00172 CV_PUT( v++, *p++ );
00173 CV_PUT( v++, *p++ );
00174 CV_PUT( v++, *p++ );
00175 CV_PUT( v++, *p++ );
00176 CV_PUT( v, *p );
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 static const int STD_MAX_CHANNELS=5;
00187 static const PixmapImageTile::Methods MethSelMatrix[STD_MAX_CHANNELS][3];
00188
00189
00190
00191 static void getpixel8_555(const PixmapImageTile *t,uint x,uint y,uint8 *p)
00192 {
00193 uint16 v=((const uint16*)t->data)[y*t->w+x];
00194 *p++ = v >> 10;
00195 *p++ = (v >> 5) & 31U;
00196 *p = v & 31U;
00197 }
00198 static void getpixel16_555(const PixmapImageTile *t,uint x,uint y,uint16 *p)
00199 {
00200 uint16 v=((const uint16*)t->data)[y*t->w+x];
00201 *p++ = v >> 10;
00202 *p++ = (v >> 5) & 31U;
00203 *p = v & 31U;
00204 }
00205 static void getpixelF_555(const PixmapImageTile *t,uint x,uint y,flt *p)
00206 {
00207 uint16 v=((const uint16*)t->data)[y*t->w+x];
00208 *p++ = P2F_5(v >> 10);
00209 *p++ = P2F_5((v >> 5) & 31U);
00210 *p = P2F_5(v & 31U);
00211 }
00212 static void putpixel8_555(PixmapImageTile *t,uint x,uint y,const uint8 *p)
00213 {
00214 uint16 v = *p++;
00215 v<<=5; v|= *p++;
00216 v<<=5; v|= *p;
00217 ((uint16*)t->data)[y*t->w+x] = v;
00218 }
00219 static void putpixel16_555(PixmapImageTile *t,uint x,uint y,const uint16 *p)
00220 {
00221 uint16 v = *p++;
00222 v<<=5; v|= *p++;
00223 v<<=5; v|= *p;
00224 ((uint16*)t->data)[y*t->w+x] = v;
00225 }
00226 static void putpixelF_555(PixmapImageTile *t,uint x,uint y,const flt *p)
00227 {
00228 uint16 v = F2P_5(*p++);
00229 v<<=5; v|= F2P_5(*p++);
00230 v<<=5; v|= F2P_5(*p);
00231 ((uint16*)t->data)[y*t->w+x] = v;
00232 }
00233
00234
00235
00236 static void getpixel8_565(const PixmapImageTile *t,uint x,uint y,uint8 *p)
00237 {
00238 uint16 v=((const uint16*)t->data)[y*t->w+x];
00239 *p++ = v >> 11;
00240 *p++ = (v >> 5) & 63U;
00241 *p = v & 31U;
00242 }
00243 static void getpixel16_565(const PixmapImageTile *t,uint x,uint y,uint16 *p)
00244 {
00245 uint16 v=((const uint16*)t->data)[y*t->w+x];
00246 *p++ = v >> 11;
00247 *p++ = (v >> 5) & 63U;
00248 *p = v & 31U;
00249 }
00250 static void getpixelF_565(const PixmapImageTile *t,uint x,uint y,flt *p)
00251 {
00252 uint16 v=((const uint16*)t->data)[y*t->w+x];
00253 *p++ = P2F_5(v >> 11);
00254 *p++ = P2F_6((v >> 5) & 63U);
00255 *p = P2F_5(v & 31U);
00256 }
00257 static void putpixel8_565(PixmapImageTile *t,uint x,uint y,const uint8 *p)
00258 {
00259 uint16 v = *p++;
00260 v<<=5; v|= *p++;
00261 v<<=6; v|= *p;
00262 ((uint16*)t->data)[y*t->w+x] = v;
00263 }
00264 static void putpixel16_565(PixmapImageTile *t,uint x,uint y,const uint16 *p)
00265 {
00266 uint16 v = *p++;
00267 v<<=5; v|= *p++;
00268 v<<=6; v|= *p;
00269 ((uint16*)t->data)[y*t->w+x] = v;
00270 }
00271 static void putpixelF_565(PixmapImageTile *t,uint x,uint y,const flt *p)
00272 {
00273 uint16 v = F2P_5(*p++);
00274 v<<=5; v|= F2P_6(*p++);
00275 v<<=6; v|= F2P_5(*p);
00276 ((uint16*)t->data)[y*t->w+x] = v;
00277 }
00278
00279
00280 static const PixmapImageTile::Methods Meth_555;
00281 static const PixmapImageTile::Methods Meth_565;
00282
00283
00284
00285 static void getpixel8_1(const PixmapImageTile *t,uint x,uint y,uint8 *p)
00286 {
00287 size_t idx = y*t->w+x;
00288 *p = ( ( ((const uint8*)t->data)[idx>>3] ) >> (idx & 7U)) & 1U;
00289 }
00290 static void getpixel16_1(const PixmapImageTile *t,uint x,uint y,uint16 *p)
00291 {
00292 size_t idx = y*t->w+x;
00293 *p = ( ( ((const uint8*)t->data)[idx>>3] ) >> (idx & 7U)) & 1U;
00294 }
00295 static void getpixelF_1(const PixmapImageTile *t,uint x,uint y,flt *p)
00296 {
00297 size_t idx = y*t->w+x;
00298 *p = flt(( ( ((const uint8*)t->data)[idx>>3] ) >> (idx & 7U)) & 1U);
00299 }
00300 static void putpixel8_1(PixmapImageTile *t,uint x,uint y,const uint8 *p)
00301 {
00302 size_t idx = y*t->w+x;
00303 if(*p) ((uint8*)t->data)[idx>>3] |= 1U << (idx & 7U);
00304 else ((uint8*)t->data)[idx>>3] &= ~uint8( 1U << (idx & 7U) );
00305 }
00306 static void putpixel16_1(PixmapImageTile *t,uint x,uint y,const uint16 *p)
00307 {
00308 size_t idx = y*t->w+x;
00309 if(*p) ((uint8*)t->data)[idx>>3] |= 1U << (idx & 7U);
00310 else ((uint8*)t->data)[idx>>3] &= ~uint8( 1U << (idx & 7U) );
00311 }
00312 static void putpixelF_1(PixmapImageTile *t,uint x,uint y,const flt *p)
00313 {
00314 size_t idx = y*t->w+x;
00315 if(*p<0.5f) ((uint8*)t->data)[idx>>3] &= ~uint8( 1U << (idx & 7U) );
00316 else ((uint8*)t->data)[idx>>3] |= 1U << (idx & 7U);
00317 }
00318
00319
00320 static const PixmapImageTile::Methods Meth_1;
00321
00322
00323
00324 static void getpixel16_12(const PixmapImageTile *t,uint x,uint y,uint16 *p)
00325 {
00326 size_t idx = y*t->w+x;
00327 const uint8 *v=&((const uint8*)t->data)[(idx*3)/2];
00328 if(idx&1) { *p = (*v & 0xfU) | (uint16(v[1]) << 4); }
00329 else { *p = (uint16(*v) << 4) | (v[1] >> 4); }
00330 }
00331 static void getpixelF_12(const PixmapImageTile *t,uint x,uint y,flt *p)
00332 {
00333 CritAssert(!"!implemented");
00334 }
00335 static void putpixel16_12(PixmapImageTile *t,uint x,uint y,const uint16 *p)
00336 {
00337 size_t idx = y*t->w+x;
00338 uint8 *v=&((uint8*)t->data)[(idx*3)/2];
00339 if(idx&1)
00340 { *v = (*v & 0xf0U) | ( *p & 0xfU ); v[1] = *p >> 4; }
00341 else
00342 { *v = *p >> 4; v[1] = (v[1] & 0xfU) | ( (*p & 0xfU) << 4 ); }
00343 }
00344 static void putpixelF_12(PixmapImageTile *t,uint x,uint y,const flt *p)
00345 {
00346 CritAssert(!"!implemented");
00347 }
00348
00349
00350 static const PixmapImageTile::Methods Meth_12;
00351 };
00352
00353
00354 const PixmapImageTile::Methods
00355 PixmapImageTileInternal::MethSelMatrix[STD_MAX_CHANNELS][3]=
00356 {
00357
00358 {
00359
00360 {
00361 &no_getpixel8,
00362 &no_getpixel16,
00363 &getpixel_1<flt,flt>,
00364 &no_putpixel8,
00365 &no_putpixel16,
00366 &putpixel_1<flt,flt>
00367 },
00368
00369 {
00370 &getpixel_1<uint8,uint8>,
00371 &getpixel_1<uint8,uint16>,
00372 &getpixel_1<uint8,flt>,
00373 &putpixel_1<uint8,uint8>,
00374 &putpixel_1<uint8,uint16>,
00375 &putpixel_1<uint8,flt>
00376 },
00377
00378 {
00379 &no_getpixel8,
00380 &getpixel_1<uint16,uint16>,
00381 &getpixel_1<uint16,flt>,
00382 &no_putpixel8,
00383 &putpixel_1<uint16,uint16>,
00384 &putpixel_1<uint16,flt>
00385 }
00386 },
00387
00388 {
00389
00390 {
00391 &no_getpixel8,
00392 &no_getpixel16,
00393 &getpixel_2<flt,flt>,
00394 &no_putpixel8,
00395 &no_putpixel16,
00396 &putpixel_2<flt,flt>
00397 },
00398
00399 {
00400 &getpixel_2<uint8,uint8>,
00401 &getpixel_2<uint8,uint16>,
00402 &getpixel_2<uint8,flt>,
00403 &putpixel_2<uint8,uint8>,
00404 &putpixel_2<uint8,uint16>,
00405 &putpixel_2<uint8,flt>
00406 },
00407
00408 {
00409 &no_getpixel8,
00410 &getpixel_2<uint16,uint16>,
00411 &getpixel_2<uint16,flt>,
00412 &no_putpixel8,
00413 &putpixel_2<uint16,uint16>,
00414 &putpixel_2<uint16,flt>
00415 }
00416 },
00417
00418 {
00419
00420 {
00421 &no_getpixel8,
00422 &no_getpixel16,
00423 &getpixel_3<flt,flt>,
00424 &no_putpixel8,
00425 &no_putpixel16,
00426 &putpixel_3<flt,flt>
00427 },
00428
00429 {
00430 &getpixel_3<uint8,uint8>,
00431 &getpixel_3<uint8,uint16>,
00432 &getpixel_3<uint8,flt>,
00433 &putpixel_3<uint8,uint8>,
00434 &putpixel_3<uint8,uint16>,
00435 &putpixel_3<uint8,flt>
00436 },
00437
00438 {
00439 &no_getpixel8,
00440 &getpixel_3<uint16,uint16>,
00441 &getpixel_3<uint16,flt>,
00442 &no_putpixel8,
00443 &putpixel_3<uint16,uint16>,
00444 &putpixel_3<uint16,flt>
00445 }
00446 },
00447
00448 {
00449
00450 {
00451 &no_getpixel8,
00452 &no_getpixel16,
00453 &getpixel_4<flt,flt>,
00454 &no_putpixel8,
00455 &no_putpixel16,
00456 &putpixel_4<flt,flt>
00457 },
00458
00459 {
00460 &getpixel_4<uint8,uint8>,
00461 &getpixel_4<uint8,uint16>,
00462 &getpixel_4<uint8,flt>,
00463 &putpixel_4<uint8,uint8>,
00464 &putpixel_4<uint8,uint16>,
00465 &putpixel_4<uint8,flt>
00466 },
00467
00468 {
00469 &no_getpixel8,
00470 &getpixel_4<uint16,uint16>,
00471 &getpixel_4<uint16,flt>,
00472 &no_putpixel8,
00473 &putpixel_4<uint16,uint16>,
00474 &putpixel_4<uint16,flt>
00475 }
00476 },
00477
00478 {
00479
00480 {
00481 &no_getpixel8,
00482 &no_getpixel16,
00483 &getpixel_5<flt,flt>,
00484 &no_putpixel8,
00485 &no_putpixel16,
00486 &putpixel_5<flt,flt>
00487 },
00488
00489 {
00490 &getpixel_5<uint8,uint8>,
00491 &getpixel_5<uint8,uint16>,
00492 &getpixel_5<uint8,flt>,
00493 &putpixel_5<uint8,uint8>,
00494 &putpixel_5<uint8,uint16>,
00495 &putpixel_5<uint8,flt>
00496 },
00497
00498 {
00499 &no_getpixel8,
00500 &getpixel_5<uint16,uint16>,
00501 &getpixel_5<uint16,flt>,
00502 &no_putpixel8,
00503 &putpixel_5<uint16,uint16>,
00504 &putpixel_5<uint16,flt>
00505 }
00506 }
00507 };
00508
00509 const PixmapImageTile::Methods PixmapImageTileInternal::Meth_555=
00510 {
00511 &getpixel8_555, &getpixel16_555, &getpixelF_555,
00512 &putpixel8_555, &putpixel16_555, &putpixelF_555
00513 };
00514
00515 const PixmapImageTile::Methods PixmapImageTileInternal::Meth_565=
00516 {
00517 &getpixel8_565, &getpixel16_565, &getpixelF_565,
00518 &putpixel8_565, &putpixel16_565, &putpixelF_565
00519 };
00520
00521
00522 const PixmapImageTile::Methods PixmapImageTileInternal::Meth_1=
00523 {
00524 &getpixel8_1, &getpixel16_1, &getpixelF_1,
00525 &putpixel8_1, &putpixel16_1, &putpixelF_1
00526 };
00527
00528
00529 const PixmapImageTile::Methods PixmapImageTileInternal::Meth_12=
00530 {
00531 &no_getpixel8, &getpixel16_12, &getpixelF_12,
00532 &no_putpixel8, &putpixel16_12, &putpixelF_12
00533 };
00534
00535
00536
00537 void PixmapImageTile::_ZapPixelFuncs()
00538 {
00539 meth.getpixel8= &PixmapImageTileInternal::no_getpixel8;
00540 meth.getpixel16=&PixmapImageTileInternal::no_getpixel16;
00541 meth.getpixelF= &PixmapImageTileInternal::no_getpixelF;
00542 meth.putpixel8= &PixmapImageTileInternal::no_putpixel8;
00543 meth.putpixel16=&PixmapImageTileInternal::no_putpixel16;
00544 meth.putpixelF= &PixmapImageTileInternal::no_putpixelF;
00545 }
00546
00547
00548 int PixmapImageTile::_SetPixelFuncs(const PixmapFormat &pf)
00549 {
00550 _ZapPixelFuncs();
00551 size=0;
00552
00553
00554 do {
00555
00556
00557 if(pf==PixmapFormat::None) break;
00558
00559
00560
00561
00562 int nchan=pf.nchannels();
00563 if(nchan>=1 && nchan<PixmapImageTileInternal::STD_MAX_CHANNELS)
00564 {
00565
00566 const PixmapImageTile::Methods *usemeth=NULL;
00567 int bytes_per_channel=0;
00568 switch(pf.SameBitsForAll())
00569 {
00570 case PixmapFormat::FloatBits:
00571 usemeth=&PixmapImageTileInternal::MethSelMatrix[nchan-1][0];
00572 bytes_per_channel=sizeof(flt);
00573 break;
00574 case 8:
00575 usemeth=&PixmapImageTileInternal::MethSelMatrix[nchan-1][1];
00576 bytes_per_channel=1;
00577 break;
00578 case 16:
00579 usemeth=&PixmapImageTileInternal::MethSelMatrix[nchan-1][2];
00580 bytes_per_channel=2;
00581 break;
00582
00583 }
00584 if(usemeth)
00585 {
00586
00587 meth=*usemeth;
00588
00589
00590 size=(size_t)w*h*nchan*bytes_per_channel;
00591
00592 break;
00593 }
00594 }
00595
00596
00597 if(pf.nchannels()==3 && pf.bits(0)==5 && pf.bits(2)==5)
00598 {
00599 if(pf.bits(1)==5)
00600 {
00601
00602 meth=PixmapImageTileInternal::Meth_555;
00603
00604
00605 size=(size_t)w*h*2;
00606
00607 break;
00608 }
00609 else if(pf.bits(1)==6)
00610 {
00611
00612 meth=PixmapImageTileInternal::Meth_565;
00613
00614
00615 size=(size_t)w*h*2;
00616 }
00617 }
00618
00619
00620 if(pf.nchannels()==1 && pf.bits(0)==1)
00621 {
00622
00623 meth=PixmapImageTileInternal::Meth_1;
00624
00625
00626 size=((size_t)w*h+7)/8;
00627 }
00628
00629
00630 return(1);
00631 } while(0);
00632
00633 return(0);
00634 }
00635
00636
00637 void PixmapImageTile::setup(const PixmapFormat &pf,uint _width,uint _height)
00638 {
00639 w=_width;
00640 h=_height;
00641 int rv=_SetPixelFuncs(pf);
00642 CritAssert(rv==0);
00643
00644 }
00645
00646
00647 PixmapImageTile::PixmapImageTile() :
00648 w(0),h(0),
00649 size(0),
00650 data(NULL)
00651 {
00652 _ZapPixelFuncs();
00653 }
00654
00655 PixmapImageTile::PixmapImageTile(const PixmapFormat &pf,
00656 uint _width,uint _height) :
00657 w(_width),h(_height)
00658 {
00659 data=NULL;
00660
00661 int rv=_SetPixelFuncs(pf);
00662 CritAssert(rv==0);
00663
00664 }
00665
00666 PixmapImageTile::~PixmapImageTile()
00667 {
00668
00669
00670 }