TBase.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. /*
  2. * Copyright (c) 2010 Nokia Corporation.
  3. */
  4. #include "TBase.h"
  5. TDWORD tengine_checksum( const TBYTE *data, const TDWORD dataLength ) {
  6. register TDWORD rval = dataLength;
  7. register TDWORD pos = 0;
  8. register TDWORD bitsToMove;
  9. while (pos<dataLength) {
  10. rval ^= (TDWORD)( data[pos] );
  11. bitsToMove = ((rval&15)+1);
  12. rval = ( (rval>>(32-bitsToMove)) | ((rval&0x0FFFFFFF)<<bitsToMove) );
  13. pos++;
  14. };
  15. return rval;
  16. };
  17. TSDWORD ITStream::writeStream( ITStream *source )
  18. {
  19. TSBYTE temp[256];
  20. TSDWORD f;
  21. TSDWORD count = 0;
  22. do {
  23. f = source->read( temp, 256 );
  24. if (f>0) {
  25. f = this->write( temp, f );
  26. if (f<1) return -1; // error.
  27. }
  28. count+=f;
  29. } while (f>0);
  30. return count;
  31. }
  32. TSDWORD ITStream::writeString( const TSBYTE *str ) {
  33. TSDWORD f = 0;
  34. while (str[f]!=0) f++;
  35. this->write( (void*)str, f+1 );
  36. return f;
  37. };
  38. TSDWORD ITStream::readString( TSBYTE *target, TSDWORD targetSize ) {
  39. TSDWORD f=0;
  40. target[0] = 0;
  41. target[targetSize-1]=0;
  42. while (f<targetSize-1) {
  43. this->read(target+f, 1);
  44. if (target[f]==0) break;
  45. f++;
  46. };
  47. return f;
  48. }
  49. CTBaseSurface::CTBaseSurface()
  50. {
  51. m_palette = 0;
  52. m_data = 0;
  53. m_width = 0;
  54. m_height = 0;
  55. m_pitch = 0;
  56. m_bpp = 0;
  57. m_flags = 0;
  58. }
  59. CTBaseSurface::~CTBaseSurface()
  60. {
  61. release();
  62. }
  63. TSDWORD CTBaseSurface::create( TSDWORD width, TSDWORD height, eTSURFACEFORMAT format )
  64. {
  65. if (width==m_width && height==m_height && format==m_format) return 0; // no need to recreate
  66. release();
  67. m_format = format;
  68. m_width = width;
  69. m_bpp = 0;
  70. m_height = height;
  71. m_pitch = width;
  72. m_palette = 0;
  73. m_flags = TSURFACEFLAG_OWNDATA;
  74. switch (format) {
  75. default:
  76. m_data = 0;
  77. m_format = eTSURFACEFORMAT_NONE;
  78. m_width = 0;
  79. m_height = 0;
  80. m_pitch = 0;
  81. m_flags = 0;
  82. return 0;
  83. case eTSURFACEFORMAT_RGB888:
  84. m_bpp = 3;
  85. m_data = new TBYTE[ width*height*3 ];
  86. return 1;
  87. case eTSURFACEFORMAT_RGBA4444:
  88. case eTSURFACEFORMAT_RGB565:
  89. case eTSURFACEFORMAT_XX88:
  90. case eTSURFACEFORMAT_SINGLECOMPONENT16BIT:
  91. m_bpp = 2;
  92. m_data = new unsigned short[ width * height ];
  93. return 1;
  94. case eTSURFACEFORMAT_SINGLECOMPONENT8BIT:
  95. case eTSURFACEFORMAT_INDEXED8BIT:
  96. m_bpp = 1;
  97. m_data = new TBYTE[ width * height ];
  98. return 1;
  99. case eTSURFACEFORMAT_RGBA8888:
  100. case eTSURFACEFORMAT_RGBA8888_PREPROCESSED:
  101. m_bpp = 4;
  102. m_data = new TDWORD[ width * height ];
  103. return 1;
  104. }
  105. }
  106. TSDWORD CTBaseSurface::setAsReference( const void *data, TSDWORD width, TSDWORD height, TSDWORD pitch, eTSURFACEFORMAT format )
  107. {
  108. release();
  109. m_flags = 0;
  110. m_format = format;
  111. m_data = (void*)data;
  112. m_pitch = pitch;
  113. m_width = width;
  114. m_height = height;
  115. m_palette = 0;
  116. switch (m_format) {
  117. case eTSURFACEFORMAT_RGB888: m_bpp = 3; break;
  118. case eTSURFACEFORMAT_RGBA4444:
  119. case eTSURFACEFORMAT_RGB565:
  120. case eTSURFACEFORMAT_SINGLECOMPONENT16BIT:
  121. m_bpp = 2;
  122. break;
  123. case eTSURFACEFORMAT_SINGLECOMPONENT8BIT:
  124. case eTSURFACEFORMAT_INDEXED8BIT:
  125. m_bpp = 1;
  126. break;
  127. case eTSURFACEFORMAT_RGBA8888:
  128. case eTSURFACEFORMAT_RGBA8888_PREPROCESSED:
  129. m_bpp = 4;
  130. break;
  131. }
  132. return 1;
  133. }
  134. void CTBaseSurface::release()
  135. {
  136. if (m_flags&TSURFACEFLAG_OWNDATA) {
  137. if (m_data)
  138. delete [] ((TDWORD*)m_data);
  139. if (m_palette) delete [] m_palette;
  140. }
  141. m_palette = 0;
  142. m_data = 0;
  143. m_width = 0;
  144. m_height = 0;
  145. m_pitch = 0;
  146. m_flags = 0;
  147. }
  148. /*
  149. struct STGAHeader {
  150. TSBYTE idlength;
  151. TSBYTE colourmaptype;
  152. TSBYTE datatypecode;
  153. short TSDWORD colourmaporigin;
  154. short TSDWORD colourmaplength;
  155. TSBYTE colourmapdepth;
  156. short TSDWORD x_origin;
  157. short TSDWORD y_origin;
  158. short width;
  159. short height;
  160. TSBYTE bitsperpixel;
  161. TSBYTE imagedescriptor;
  162. TSBYTE idstring[256];
  163. }; // header for TGA, files
  164. */
  165. TSDWORD CTBaseSurface::writeTGA( ITStream *target ) {
  166. if (!target) return 0;
  167. STGAHeader header; // this must be filled.
  168. memset( &header, 0, sizeof(STGAHeader) ); // zero all
  169. header.bitsperpixel = m_bpp*8;
  170. header.width = m_width;
  171. header.height = m_height;
  172. header.datatypecode = 2;
  173. target->write( &header.idlength, 1 );
  174. target->write( &header.colourmaptype, 1 );
  175. target->write( &header.datatypecode, 1 );
  176. target->write( &header.colourmaporigin, 2 );
  177. target->write( &header.colourmaplength, 2 );
  178. target->write( &header.colourmapdepth, 1 );
  179. target->write( &header.x_origin, 2 );
  180. target->write( &header.y_origin, 2 );
  181. target->write( &header.width, 2 );
  182. target->write( &header.height, 2 );
  183. target->write( &header.bitsperpixel, 1 );
  184. target->write( &header.imagedescriptor, 1 );
  185. if (header.idlength>0) { // read the id.
  186. target->write(header.idstring, header.idlength );
  187. }
  188. for (TSDWORD y = 0; y<m_height; y++) {
  189. target->write( (char*)m_data + m_bpp*(m_height-y-1)*m_pitch, m_bpp*m_width );
  190. };
  191. return 1;
  192. };
  193. TSDWORD CTBaseSurface::readTGA( ITStream *source )
  194. {
  195. if (!source) return 0;
  196. release();
  197. STGAHeader header;
  198. source->read( &header.idlength, 1 );
  199. source->read( &header.colourmaptype, 1 );
  200. source->read( &header.datatypecode, 1 );
  201. source->read( &header.colourmaporigin, 2 );
  202. source->read( &header.colourmaplength, 2 );
  203. source->read( &header.colourmapdepth, 1 );
  204. source->read( &header.x_origin, 2 );
  205. source->read( &header.y_origin, 2 );
  206. source->read( &header.width, 2 );
  207. source->read( &header.height, 2 );
  208. source->read( &header.bitsperpixel, 1 );
  209. source->read( &header.imagedescriptor, 1 );
  210. if (header.idlength>0) { // read the id.
  211. source->read(header.idstring, header.idlength );
  212. }
  213. TBYTE *palette = 0;
  214. if (header.colourmaplength>0) {
  215. TSDWORD paletteLength = header.colourmaplength * header.colourmapdepth / 8;
  216. palette = new TBYTE[ paletteLength ];
  217. source->read( palette, paletteLength );
  218. }
  219. m_palette = 0;
  220. m_width = header.width;
  221. m_height = header.height;
  222. m_pitch = header.width;
  223. m_flags = TSURFACEFLAG_OWNDATA;
  224. m_data = 0;
  225. if (header.datatypecode == 1) {
  226. m_palette = palette;
  227. } else {
  228. if (palette) delete [] palette;
  229. palette = 0;
  230. }
  231. TSDWORD bytes = m_width * m_height * header.bitsperpixel / 8;
  232. m_data = new TBYTE[ bytes ];
  233. TSDWORD linelength = (m_width * header.bitsperpixel) >> 3;
  234. if ((header.imagedescriptor&32)==0) { //image flipped
  235. TBYTE *t = (TBYTE*)m_data + m_pitch * (m_height-1) * (header.bitsperpixel>>3);
  236. // do the flip and copy the data.
  237. for (TSDWORD f=0; f<header.height; f++) {
  238. if (source->read(t, linelength ) != linelength) {
  239. //printf("ERROR LOADING TGA.... RLE-COMPRESSED?\n");
  240. release();
  241. return 0;
  242. };
  243. t-=linelength;
  244. }
  245. } else {
  246. source->read( m_data, linelength*header.height );
  247. };
  248. m_bpp = header.bitsperpixel/8;
  249. if (m_bpp<1) m_bpp = 1; // Warning?
  250. switch ( m_bpp )
  251. {
  252. case 4: m_format = eTSURFACEFORMAT_RGBA8888; break;
  253. case 3: m_format = eTSURFACEFORMAT_RGB888; break;
  254. case 2: m_format = eTSURFACEFORMAT_RGB565; break;
  255. case 1:
  256. if (m_palette)
  257. m_format = eTSURFACEFORMAT_INDEXED8BIT;
  258. else
  259. m_format = eTSURFACEFORMAT_SINGLECOMPONENT8BIT;
  260. break;
  261. }
  262. return 1;
  263. }
  264. TSDWORD CTBaseSurface::bltPrepeare(
  265. TSDWORD x, TSDWORD y,
  266. CTBaseSurface &source,
  267. TSDWORD &ibltwidth, TSDWORD &ibltheight,
  268. TSDWORD &ibltsourceoffset )
  269. {
  270. if (ibltwidth<1) ibltwidth = source.getWidth();
  271. if (ibltheight<1) ibltheight = source.getHeight();
  272. ibltsourceoffset = 0;
  273. // do clippping agains this image
  274. if (y<0) {
  275. ibltheight+=y;
  276. ibltsourceoffset-=y*source.getPitch();
  277. y =0;
  278. }
  279. if (x<0) {
  280. ibltwidth+=x;
  281. ibltsourceoffset -= x;
  282. x =0;
  283. }
  284. if (x+ibltwidth>=getWidth()) {
  285. ibltwidth -= ( (x+ibltwidth)-getWidth() );
  286. }
  287. if (y+ibltheight>=getHeight()) {
  288. ibltheight -= ( (y+ibltheight)-getHeight() );
  289. }
  290. if (ibltwidth>0 && ibltheight>0) return m_pitch*y+x; else return 0;
  291. }
  292. void CTBaseSurface::toStream( ITStream *target ) {
  293. target->write( &m_format, 4 );
  294. target->write( &m_width, 4 );
  295. target->write( &m_height, 4 );
  296. TBYTE hasPalette = 0;
  297. if (m_palette) hasPalette = 1;
  298. target->write( &hasPalette, 1 );
  299. if (hasPalette) {
  300. target->write( m_palette, 256*3 );
  301. };
  302. for (TSDWORD f=0; f<m_height; f++)
  303. target->write( ((TBYTE*)m_data)+f*m_pitch*m_bpp, m_width*m_bpp );
  304. };
  305. TBOOL CTBaseSurface::fromStream( ITStream *source ) {
  306. release();
  307. eTSURFACEFORMAT format;
  308. TSDWORD width, height;
  309. if (source->read( &format, 4 ) != 4) return TFALSE;
  310. if (source->read( &width, 4 ) != 4) return TFALSE;
  311. if (source->read( &height, 4 ) != 4) return TFALSE;
  312. TBYTE hasPalette;
  313. source->read( &hasPalette, 1 );
  314. if (create(width,height,format) == 0) return TFALSE;
  315. if (hasPalette) {
  316. m_palette = new TBYTE[ 256*3 ];
  317. source->read( m_palette, 256*3 );
  318. };
  319. if (source->read(m_data, m_width*m_height*m_bpp) != m_width*m_height*m_bpp) return TFALSE;
  320. return TTRUE;
  321. };
  322. CTBaseSurface *CTBaseSurface::changeFormat( eTSURFACEFORMAT copyFormat ) {
  323. if (!m_data) return 0;
  324. CTBaseSurface *rval = new CTBaseSurface;
  325. rval->create( m_width, m_height, copyFormat );
  326. // do the copy.
  327. switch (m_format) {
  328. default:
  329. delete rval; // not implemented
  330. return 0;
  331. break;
  332. case eTSURFACEFORMAT_INDEXED8BIT:
  333. if (copyFormat==eTSURFACEFORMAT_RGBA8888) {
  334. for (TSDWORD f=0; f<m_height; f++) {
  335. TDWORD *t = (TDWORD*)rval->getData()+rval->getPitch()*f;
  336. TBYTE *s = (TBYTE*)getData()+getPitch()*f;
  337. for (TSDWORD x=0; x<m_width; x++) {
  338. *t = ( m_palette[ (*s)*3 + 0 ] << 0) |
  339. ( m_palette[ (*s)*3 + 1 ] << 8) |
  340. ( m_palette[ (*s)*3 + 2 ] << 16) |
  341. (255<<24); // full alpha
  342. t++;
  343. s++;
  344. };
  345. };
  346. return rval;
  347. };
  348. delete rval;
  349. return 0;
  350. break;
  351. case eTSURFACEFORMAT_RGBA4444:
  352. if (copyFormat == eTSURFACEFORMAT_RGBA8888_PREPROCESSED) {
  353. for (TSDWORD f=0; f<m_height; f++) {
  354. TDWORD *t = (TDWORD*)rval->getData()+rval->getPitch()*f;
  355. unsigned short *s = (unsigned short*)getData()+getPitch()*f;
  356. for (TSDWORD x=0; x<m_width; x++) {
  357. *t = (TDWORD)(
  358. ((*s)&15) |
  359. ((((*s)>>4)&15)<<8) |
  360. ((((*s)>>8)&15)<<16) |
  361. ((((*s)>>12)&15)<<24) );
  362. t++;s++;
  363. };
  364. }
  365. return rval;
  366. };
  367. delete rval;
  368. return 0;
  369. break;
  370. case eTSURFACEFORMAT_RGB888:
  371. if (copyFormat == eTSURFACEFORMAT_RGBA8888) {
  372. for (TSDWORD f=0; f<m_height; f++) {
  373. TDWORD *t = (TDWORD*)rval->getData()+rval->getPitch()*f;
  374. TBYTE *s = (TBYTE*)getData()+getPitch()*f*3;
  375. for (TSDWORD x=0; x<m_width; x++) {
  376. *t = (TDWORD)( s[0] | (s[1]<<8) | (s[2]<<16) );
  377. t++;s+=3;
  378. };
  379. }
  380. return rval;
  381. } else if ( copyFormat== eTSURFACEFORMAT_RGB565 ) {
  382. for (TSDWORD f=0; f<m_height; f++) {
  383. TWORD *t = (TWORD*)rval->getData()+rval->getPitch()*f;
  384. TBYTE *s = (TBYTE*)getData()+getPitch()*f*3;
  385. for (TSDWORD x=0; x<m_width; x++) {
  386. *t = (TWORD)( (s[2]>>3) | ((s[1]>>2)<<5) | ((s[0]>>3)<<11) );
  387. t++;s+=3;
  388. };
  389. }
  390. return rval;
  391. };
  392. delete rval;
  393. return 0;
  394. case eTSURFACEFORMAT_RGBA8888: // FROM RGBA8888.
  395. {
  396. if (copyFormat == eTSURFACEFORMAT_RGBA4444) {
  397. for (TSDWORD f=0; f<m_height; f++) {
  398. unsigned short *t = (unsigned short*)rval->getData()+rval->getPitch()*f;
  399. TDWORD *s = (TDWORD*)getData()+getPitch()*f;
  400. for (TSDWORD x=0; x<m_width; x++) {
  401. *t = (unsigned short)((((*s)>>4)&15) |
  402. ((((*s)>>12)&15)<<4) |
  403. ((((*s)>>20)&15)<<8) |
  404. ((((*s)>>28)&15)<<12));
  405. t++;s++;
  406. };
  407. }
  408. return rval;
  409. } else if (copyFormat == eTSURFACEFORMAT_RGB888) {
  410. for (TSDWORD f=0; f<m_height; f++) {
  411. unsigned short *t = (unsigned short*)rval->getData()+rval->getPitch()*f;
  412. TBYTE *s = (TBYTE*)getData()+getPitch()*f*3;
  413. for (TSDWORD x=0; x<m_width; x++) {
  414. *t = (unsigned short)((((s[0])>>4)&15) |
  415. (((s[1]>>4)&15)<<4) |
  416. (((s[2]>>4)&15)<<8) );
  417. t++;s+=3;
  418. };
  419. }
  420. } else if ( copyFormat== eTSURFACEFORMAT_RGB565 ) { // NOTE, .. check that this works when converted to byte
  421. for (TSDWORD f=0; f<m_height; f++) {
  422. TWORD *t = (TWORD*)rval->getData()+rval->getPitch()*f;
  423. TBYTE *s = (TBYTE*)getData()+getPitch()*f*4;
  424. for (TSDWORD x=0; x<m_width; x++) {
  425. *t = (TWORD)( (s[2]>>3) | ((s[1]>>2)<<5) | ((s[0]>>3)<<11) );
  426. t++;s+=4;
  427. };
  428. }
  429. return rval;
  430. };
  431. delete rval;
  432. return 0;
  433. }
  434. break;
  435. };
  436. return rval;
  437. };