convtest.pas 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. {$MODE objfpc}
  2. {$I endian.pas}
  3. Uses
  4. SysUtils, ptc;
  5. Const
  6. destXSize = {480}320;
  7. destYSize = {300}200;
  8. Var
  9. image : TPTCSurface;
  10. surface : TPTCSurface;
  11. format : TPTCFormat;
  12. TestNum : Integer;
  13. Function fb(q : int32) : Integer;
  14. Begin
  15. fb := 0;
  16. While (q And 1) = 0 Do
  17. Begin
  18. Inc(fb);
  19. q := q Shr 1;
  20. End;
  21. End;
  22. Function nb(q : int32) : Integer;
  23. Begin
  24. nb := 0;
  25. While q <> 0 Do
  26. Begin
  27. Inc(nb);
  28. q := q And (q - 1);
  29. End;
  30. End;
  31. Procedure generic(src, dest : TPTCSurface);
  32. Var
  33. X, Y : Integer;
  34. XSize, YSize : Integer;
  35. r, g, b : int32;
  36. pix : int32;
  37. Psrc, Pdest : Pchar8;
  38. srcbits : Integer;
  39. Srmask, Sgmask, Sbmask : int32;
  40. Srmasknb, Sgmasknb, Sbmasknb : Integer;
  41. Srmaskfb, Sgmaskfb, Sbmaskfb : Integer;
  42. destbits : Integer;
  43. Drmask, Dgmask, Dbmask : int32;
  44. Drmasknb, Dgmasknb, Dbmasknb : Integer;
  45. Drmaskfb, Dgmaskfb, Dbmaskfb : Integer;
  46. Begin
  47. XSize := dest.width;
  48. YSize := dest.height;
  49. srcbits := src.format.bits;
  50. Srmask := src.format.r;
  51. Sgmask := src.format.g;
  52. Sbmask := src.format.b;
  53. Srmasknb := nb(Srmask);
  54. Sgmasknb := nb(Sgmask);
  55. Sbmasknb := nb(Sbmask);
  56. Srmaskfb := fb(Srmask);
  57. Sgmaskfb := fb(Sgmask);
  58. Sbmaskfb := fb(Sbmask);
  59. destbits := dest.format.bits;
  60. Drmask := dest.format.r;
  61. Dgmask := dest.format.g;
  62. Dbmask := dest.format.b;
  63. Drmasknb := nb(Drmask);
  64. Dgmasknb := nb(Dgmask);
  65. Dbmasknb := nb(Dbmask);
  66. Drmaskfb := fb(Drmask);
  67. Dgmaskfb := fb(Dgmask);
  68. Dbmaskfb := fb(Dbmask);
  69. { Writeln(Srmasknb, ' ', Drmasknb);}
  70. Psrc := src.lock;
  71. Pdest := dest.lock;
  72. For Y := 0 To YSize - 1 Do
  73. For X := 0 To XSize - 1 Do
  74. Begin
  75. Case srcbits Of
  76. 32 : Begin
  77. pix := (Pint32(Psrc))^;
  78. Inc(Psrc, 4);
  79. End;
  80. 24 : Begin
  81. {$IFDEF FPC_LITTLE_ENDIAN}
  82. pix := (Psrc^) Or ((Psrc + 1)^ Shl 8) Or ((Psrc + 2)^ Shl 16);
  83. {$ELSE FPC_LITTLE_ENDIAN}
  84. pix := (Psrc^ Shl 16) Or ((Psrc + 1)^ Shl 8) Or ((Psrc + 2)^);
  85. {$ENDIF FPC_LITTLE_ENDIAN}
  86. Inc(Psrc, 3);
  87. End;
  88. 16 : Begin
  89. pix := (Pshort16(Psrc))^;
  90. Inc(Psrc, 2);
  91. End;
  92. 8 : Begin
  93. pix := Psrc^;
  94. Inc(Psrc);
  95. End;
  96. End;
  97. r := pix And Srmask;
  98. g := pix And Sgmask;
  99. b := pix And Sbmask;
  100. r := r Shr Srmaskfb;
  101. g := g Shr Sgmaskfb;
  102. b := b Shr Sbmaskfb;
  103. If (Drmasknb - Srmasknb) >= 0 Then
  104. r := r Shl (Drmasknb - Srmasknb)
  105. Else
  106. r := r Shr (Srmasknb - Drmasknb);
  107. If (Dgmasknb - Sgmasknb) >= 0 Then
  108. g := g Shl (Dgmasknb - Sgmasknb)
  109. Else
  110. g := g Shr (Sgmasknb - Dgmasknb);
  111. If (Dbmasknb - Sbmasknb) >= 0 Then
  112. b := b Shl (Dbmasknb - Sbmasknb)
  113. Else
  114. b := b Shr (Sbmasknb - Dbmasknb);
  115. r := r Shl Drmaskfb;
  116. g := g Shl Dgmaskfb;
  117. b := b Shl Dbmaskfb;
  118. pix := r Or g Or b;
  119. Case destbits Of
  120. 32 : Begin
  121. (Pint32(Pdest))^ := pix;
  122. Inc(Pdest, 4);
  123. End;
  124. 24 : Begin
  125. {$IFDEF FPC_LITTLE_ENDIAN}
  126. Pdest^ := pix And $FF;
  127. (Pdest + 1)^ := (pix Shr 8) And $FF;
  128. (Pdest + 2)^ := (pix Shr 16) And $FF;
  129. {$ELSE FPC_LITTLE_ENDIAN}
  130. Pdest^ := (pix Shr 16) And $FF;
  131. (Pdest + 1)^ := (pix Shr 8) And $FF;
  132. (Pdest + 2)^ := pix And $FF;
  133. {$ENDIF FPC_LITTLE_ENDIAN}
  134. Inc(Pdest, 3);
  135. End;
  136. 16 : Begin
  137. (Pshort16(Pdest))^ := pix;
  138. Inc(Pdest, 2);
  139. End;
  140. 8 : Begin
  141. Pdest^ := pix;
  142. Inc(Pdest);
  143. End;
  144. End;
  145. End;
  146. src.unlock;
  147. dest.unlock;
  148. End;
  149. Procedure test(sbits : Integer; sr, sg, sb : int32;
  150. dbits : Integer; dr, dg, db, da : int32);
  151. Var
  152. srcformat, destformat : TPTCFormat;
  153. src, dest : TPTCSurface;
  154. F : File;
  155. Begin
  156. Writeln(sbits, ' ', sr, ' ', sg, ' ', sb, ' ', dbits, ' ', dr, ' ', dg, ' ', db, ' ', da);
  157. srcformat := TPTCFormat.Create(sbits, sr, sg, sb);
  158. destformat := TPTCFormat.Create(dbits, dr, dg, db, da);
  159. src := TPTCSurface.Create(320, 200, srcformat);
  160. dest := TPTCSurface.Create(destXSize, destYSize, destformat);
  161. generic(image, src);
  162. src.copy(dest);
  163. { generic(src, dest);}
  164. generic(dest, surface);
  165. src.Destroy;
  166. dest.Destroy;
  167. srcformat.Destroy;
  168. destformat.Destroy;
  169. Inc(TestNum);
  170. ASSign(F, 'test' + IntToStr(TestNum) + '.raw');
  171. Rewrite(F, 1);
  172. BlockWrite(F, surface.lock^, surface.height * surface.pitch);
  173. surface.unlock;
  174. Close(F);
  175. End;
  176. Procedure test(sbits : Integer; sr, sg, sb : int32;
  177. dbits : Integer; dr, dg, db : int32);
  178. Begin
  179. test(sbits, sr, sg, sb, dbits, dr, dg, db, 0);
  180. End;
  181. Procedure load(surface : TPTCSurface; filename : String);
  182. Var
  183. F : File;
  184. width, height : Integer;
  185. pixels : PByte;
  186. y : Integer;
  187. tmp : TPTCFormat;
  188. tmp2 : TPTCPalette;
  189. Begin
  190. ASSign(F, filename);
  191. Reset(F, 1);
  192. Seek(F, 18);
  193. width := surface.width;
  194. height := surface.height;
  195. pixels := surface.lock;
  196. For y := height - 1 DownTo 0 Do
  197. BlockRead(F, pixels[width * y * 3], width * 3);
  198. surface.unlock;
  199. End;
  200. Begin
  201. TestNum := 0;
  202. Try
  203. {$IFDEF FPC_LITTLE_ENDIAN}
  204. format := TPTCFormat.Create(24, $00FF0000, $0000FF00, $000000FF);
  205. {$ELSE FPC_LITTLE_ENDIAN}
  206. format := TPTCFormat.Create(24, $000000FF, $0000FF00, $00FF0000);
  207. {$ENDIF FPC_LITTLE_ENDIAN}
  208. surface := TPTCSurface.Create(destXSize, destYSize, format);
  209. image := TPTCSurface.Create(320, 200, format);
  210. load(image, '../examples/image.tga');
  211. format.Free;
  212. Writeln('testing equal converters');
  213. {test equal converters}
  214. test(32, $00FF0000, $0000FF00, $000000FF, 32, $00FF0000, $0000FF00, $000000FF);
  215. test(24, $FF0000, $00FF00, $0000FF, 24, $FF0000, $00FF00, $0000FF);
  216. test(16, $F800, $07E0, $001F, 16, $F800,$07E0, $001F);
  217. test( 8, $E0, $1C, $03, 8, $E0, $1C, $03);
  218. Writeln('testing generic converters');
  219. {test generic}
  220. test(32, $FF000000, $000000FF, $000FF000, 32, $000FF000, $0FF00000, $000000FF);
  221. test(32, $FF000000, $000000FF, $000FF000, 24, $00FF00, $FF0000, $000000FF);
  222. test(32, $FF000000, $000000FF, $000FF000, 16, $F000, $0F00, $00F0);
  223. test(32, $FF000000, $000000FF, $000FF000, 8, $0C, $03, $F0);
  224. test(24, $FF0000, $0000FF, $00FF00, 32, $000FF000, $0FF00000, $000000FF);
  225. test(24, $FF0000, $0000FF, $00FF00, 24, $00FF00, $FF0000, $000000FF);
  226. test(24, $FF0000, $0000FF, $00FF00, 16, $F000, $0F00, $00F0);
  227. test(24, $FF0000, $0000FF, $00FF00, 8, $0C, $03, $F0);
  228. test(16, $001F, $F800, $07E0, 32, $000FF000, $0FF00000, $000000FF);
  229. test(16, $001F, $F800, $07E0, 24, $00FF00, $FF0000, $000000FF);
  230. test(16, $001F, $F800, $07E0, 16, $F000, $0F00, $00F0);
  231. test(16, $001F, $F800, $07E0, 8, $0C, $03, $F0);
  232. // test(8, $03, $E0, $1C, 32, $000FF000, $0FF00000, $000000FF); {unsupported}
  233. // test(8, $03, $E0, $1C, 24, $00FF00, $FF0000, $000000FF); {unsupported}
  234. // test(8, $03, $E0, $1C, 16, $F000, $0F00, $00F0); {unsupported}
  235. // test(8, $03, $E0, $1C, 8, $0C, $03, $F0); {unsupported}
  236. Writeln('testing specialized converters');
  237. {From 32 bit RGB 888}
  238. test(32,$ff0000,$ff00,$ff,16,$f800,$7e0,$1f); {16RGB565 }
  239. test(32,$ff0000,$ff00,$ff, 8,$e0,$1c,$3); { 8RGB332 }
  240. test(32,$ff0000,$ff00,$ff,16,$7c00,$3e0,$1f); { 16RGB555 }
  241. test(32,$ff0000,$ff00,$ff,24,$ff0000,$ff00,$ff); { 24RGB888 }
  242. test(32,$ff0000,$ff00,$ff,32,$ff,$ff00,$ff0000); { 32BGR888 }
  243. test(32,$ff0000,$ff00,$ff,16,$1f,$7e0,$f800); { 16BGR565 }
  244. test(32,$ff0000,$ff00,$ff,16,$1f,$3e0,$7c00); { 16BGR555 }
  245. test(32,$ff0000,$ff00,$ff,32,$ff000000,$ff0000,$ff00,$ff); { 32RGBA888 }
  246. test(32,$ff0000,$ff00,$ff,32,$ff00,$ff0000,$ff000000,$ff); { 32BGRA888 }
  247. test(32,$ff0000,$ff00,$ff,24,$ff,$ff00,$ff0000); { 24BGR888 }
  248. {From 24 bit RGB 888}
  249. test(24,$ff0000,$ff00,$ff,32,$ff0000,$ff00,$ff); { 32RGB888 }
  250. test(24,$ff0000,$ff00,$ff,16,$f800,$7e0,$1f); { 16RGB565 }
  251. test(24,$ff0000,$ff00,$ff, 8,$e0,$1c,$3); { 8RGB332 }
  252. test(24,$ff0000,$ff00,$ff,16,$7c00,$3e0,$1f); { 16RGB555 }
  253. test(24,$ff0000,$ff00,$ff,32,$ff,$ff00,$ff0000); { 32BGR888 }
  254. test(24,$ff0000,$ff00,$ff,16,$1f,$7e0,$f800); { 16BGR565 }
  255. test(24,$ff0000,$ff00,$ff,16,$1f,$3e0,$7c00); { 16BGR555 }
  256. test(24,$ff0000,$ff00,$ff,32,$ff000000,$ff0000,$ff00,$ff); { 32RGBA888 }
  257. test(24,$ff0000,$ff00,$ff,32,$ff00,$ff0000,$ff000000,$ff); { 32BGRA888 }
  258. test(24,$ff0000,$ff00,$ff,24,$ff,$ff00,$ff0000); { 24BGR888 }
  259. {From 16 bit RGB 565}
  260. test(16,$f800,$7e0,$1f,32,$ff0000,$ff00,$ff); { 32RGB888 }
  261. test(16,$f800,$7e0,$1f, 8,$e0,$1c,$3); { 8RGB332 }
  262. test(16,$f800,$7e0,$1f,16,$7c00,$3e0,$1f); { 16RGB555 }
  263. test(16,$f800,$7e0,$1f,24,$ff0000,$ff00,$ff); { 24RGB888 }
  264. test(16,$f800,$7e0,$1f,32,$ff,$ff00,$ff0000); { 32BGR888 }
  265. test(16,$f800,$7e0,$1f,16,$1f,$7e0,$f800); { 16BGR565 }
  266. test(16,$f800,$7e0,$1f,16,$1f,$3e0,$7c00); { 16BGR555 }
  267. test(16,$f800,$7e0,$1f,32,$ff000000,$ff0000,$ff00,$ff); { 32RGBA888 }
  268. test(16,$f800,$7e0,$1f,32,$ff00,$ff0000,$ff000000,$ff); { 32BGRA888 }
  269. test(16,$f800,$7e0,$1f,24,$ff,$ff00,$ff0000); { 24BGR888 }
  270. {From 32 bit muhmu}
  271. test(32,$ff00000,$3fc00,$ff,32,$ff0000,$ff00,$ff); { 32RGB888 }
  272. test(32,$ff00000,$3fc00,$ff,16,$f800,$7e0,$1f); { 16RGB565 }
  273. test(32,$ff00000,$3fc00,$ff, 8,$e0,$1c,$3); { 8RGB332 }
  274. test(32,$ff00000,$3fc00,$ff,16,$7c00,$3e0,$1f); { 16RGB555 }
  275. test(32,$ff00000,$3fc00,$ff,24,$ff0000,$ff00,$ff); { 24RGB888 }
  276. test(32,$ff00000,$3fc00,$ff,32,$ff,$ff00,$ff0000); { 32BGR888 }
  277. test(32,$ff00000,$3fc00,$ff,16,$1f,$7e0,$f800); { 16BGR565 }
  278. test(32,$ff00000,$3fc00,$ff,16,$1f,$3e0,$7c00); { 16BGR555 }
  279. test(32,$ff00000,$3fc00,$ff,32,$ff000000,$ff0000,$ff00,$ff); { 32RGBA888 }
  280. test(32,$ff00000,$3fc00,$ff,32,$ff00,$ff0000,$ff000000,$ff); { 32BGRA888 }
  281. test(32,$ff00000,$3fc00,$ff,24,$ff,$ff00,$ff0000); { 24BGR888 }
  282. surface.Destroy;
  283. image.Destroy;
  284. Except
  285. On error : TPTCError Do
  286. error.report;
  287. End;
  288. End.