/packages/hermes/src/p_16.inc

https://github.com/slibre/freepascal · Pascal · 783 lines · 555 code · 130 blank · 98 comment · 34 complexity · aa2bd5c23e40f919cdc257b8026f1aeb MD5 · raw file

  1. {
  2. Free Pascal port of the Hermes C library.
  3. Copyright (C) 2001-2003 Nikolay Nikolov (nickysn@users.sourceforge.net)
  4. Original C version by Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version
  9. with the following modification:
  10. As a special exception, the copyright holders of this library give you
  11. permission to link this library with independent modules to produce an
  12. executable, regardless of the license terms of these independent modules,and
  13. to copy and distribute the resulting executable under terms of your choice,
  14. provided that you also meet, for each linked independent module, the terms
  15. and conditions of the license of that module. An independent module is a
  16. module which is not derived from or based on this library. If you modify
  17. this library, you may extend this exception to your version of the library,
  18. but you are not obligated to do so. If you do not wish to do so, delete this
  19. exception statement from your version.
  20. This library is distributed in the hope that it will be useful,
  21. but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  23. Lesser General Public License for more details.
  24. You should have received a copy of the GNU Lesser General Public
  25. License along with this library; if not, write to the Free Software
  26. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27. }
  28. {
  29. 16 bit to * converters for the HERMES library
  30. Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
  31. This source code is licensed under the GNU LGPL
  32. Please refer to the file COPYING.LIB contained in the distribution for
  33. licensing conditions
  34. }
  35. { TO 32 BIT RGB }
  36. procedure ConvertP_16rgb565_32rgb888(source, dest: PUint8; count, inc_source: DWord); cdecl;
  37. var
  38. d_pixel: Uint32;
  39. begin
  40. repeat
  41. d_pixel := PUint16(source)^;
  42. d_pixel := ((d_pixel and $f800) shl 8) or ((d_pixel and $7e0) shl 5) or
  43. ((d_pixel and $1f) shl 3) or $030103;
  44. PUint32(dest)^ := d_pixel;
  45. Inc(source, 2);
  46. Inc(dest, 4);
  47. Dec(count);
  48. until count = 0;
  49. end;
  50. { TO 32 BIT BGR }
  51. procedure ConvertP_16rgb565_32bgr888(source, dest: PUint8; count, inc_source: DWord); cdecl;
  52. var
  53. d_pixel: Uint32;
  54. begin
  55. repeat
  56. d_pixel := PUint16(source)^;
  57. d_pixel := ((d_pixel and $f800) shr 8) or ((d_pixel and $7e0) shl 5) or
  58. ((d_pixel and $1f) shl 19) or $030103;
  59. PUint32(dest)^ := d_pixel;
  60. Inc(source, 2);
  61. Inc(dest, 4);
  62. Dec(count);
  63. until count = 0;
  64. end;
  65. { TO 32 BIT RGBA }
  66. procedure ConvertP_16rgb565_32rgba888(source, dest: PUint8; count, inc_source: DWord); cdecl;
  67. var
  68. d_pixel: Uint32;
  69. begin
  70. repeat
  71. d_pixel := PUint16(source)^;
  72. d_pixel := ((d_pixel and $f800) shl 8) or ((d_pixel and $7e0) shl 5) or
  73. ((d_pixel and $1f) shl 3) or $030103;
  74. PUint32(dest)^ := (d_pixel shl 8) or $ff;
  75. Inc(source, 2);
  76. Inc(dest, 4);
  77. Dec(count);
  78. until count = 0;
  79. end;
  80. { TO 32 BIT BGRA }
  81. procedure ConvertP_16rgb565_32bgra888(source, dest: PUint8; count, inc_source: DWord); cdecl;
  82. var
  83. d_pixel: Uint32;
  84. begin
  85. repeat
  86. d_pixel := PUint16(source)^;
  87. d_pixel := ((d_pixel and $f800) shr 8) or ((d_pixel and $7e0) shl 5) or
  88. ((d_pixel and $1f) shl 19) or $030103;
  89. PUint32(dest)^ := (d_pixel shl 8) or $ff;
  90. Inc(source, 2);
  91. Inc(dest, 4);
  92. Dec(count);
  93. until count = 0;
  94. end;
  95. { TO 24 BIT RGB }
  96. procedure ConvertP_16rgb565_24rgb888(source, dest: PUint8; count, inc_source: DWord); cdecl;
  97. var
  98. d_pixel: Uint32;
  99. d_ptr: PUint8;
  100. begin
  101. d_ptr := PUint8(@d_pixel) + (R_32 - R_24);
  102. repeat
  103. d_pixel := PUint16(source)^;
  104. d_pixel := ((d_pixel and $f800) shl 8) or ((d_pixel and $7e0) shl 5) or
  105. ((d_pixel and $1f) shl 3) or $030103;
  106. (dest + 0)^ := (d_ptr + 0)^;
  107. (dest + 1)^ := (d_ptr + 1)^;
  108. (dest + 2)^ := (d_ptr + 2)^;
  109. Inc(source, 2);
  110. Inc(dest, 3);
  111. Dec(count);
  112. until count = 0;
  113. end;
  114. { TO 24 BIT BGR }
  115. procedure ConvertP_16rgb565_24bgr888(source, dest: PUint8; count, inc_source: DWord); cdecl;
  116. var
  117. d_pixel: Uint32;
  118. d_ptr: PUint8;
  119. begin
  120. d_ptr := PUint8(@d_pixel) + (R_32 - R_24);
  121. repeat
  122. d_pixel := PUint16(source)^;
  123. d_pixel := ((d_pixel and $f800) shl 8) or ((d_pixel and $7e0) shl 5) or
  124. ((d_pixel and $1f) shl 3) or $030103;
  125. { Red and blue are swapped here }
  126. (dest + 0)^ := (d_ptr + 2)^;
  127. (dest + 1)^ := (d_ptr + 1)^;
  128. (dest + 2)^ := (d_ptr + 0)^;
  129. Inc(source, 2);
  130. Inc(dest, 3);
  131. Dec(count);
  132. until count = 0;
  133. end;
  134. { TO 16 BIT BGR 565 }
  135. procedure ConvertP_16rgb565_16bgr565(source, dest: PUint8; count, inc_source: DWord); cdecl;
  136. var
  137. i: DWord;
  138. s_pixel: Uint32;
  139. begin
  140. { if we are not aligned to a dword, try and convert a single pixel }
  141. if (PtrUInt(dest) and $3) <> 0 then
  142. begin
  143. s_pixel := PUint16(source)^;
  144. { Swap around R and B, leave G unchanged }
  145. s_pixel := (s_pixel shr 11) or (s_pixel and $7e0) or
  146. ((s_pixel shl 11) and $f800);
  147. PUint16(dest)^ := s_pixel;
  148. Dec(count);
  149. Inc(dest, 2); Inc(source, 2);
  150. end;
  151. { Now copy blocks of dwords }
  152. for i := 1 to count shr 1 do
  153. begin
  154. s_pixel := PUint32(source)^;
  155. { Leave G unchanged, shift R to the right and B to the left }
  156. s_pixel := (s_pixel and $07e007e0) or ((s_pixel and $f800f800) shr 11) or
  157. ((s_pixel and $001f001f) shl 11);
  158. PUint32(dest)^ := s_pixel;
  159. Inc(source, 4); Inc(dest, 4);
  160. end;
  161. if (count and 1) <> 0 then
  162. begin
  163. s_pixel := PUint16(source)^;
  164. { Swap around R and B, leave G unchanged }
  165. s_pixel := (s_pixel shr 11) or (s_pixel and $7e0) or
  166. ((s_pixel shl 11) and $f800);
  167. PUint16(dest)^ := s_pixel;
  168. end;
  169. end;
  170. { TO 16 BIT RGB 555 }
  171. procedure ConvertP_16rgb565_16rgb555(source, dest: PUint8; count, inc_source: DWord); cdecl;
  172. var
  173. i: DWord;
  174. s_pixel: Uint32;
  175. begin
  176. { if we are not aligned to a dword, try and convert a single pixel }
  177. if (PtrUInt(dest) and $3) <> 0 then
  178. begin
  179. s_pixel := PUint16(source)^;
  180. { Leave blue untouched, mask red and shift by one, mask green and shift
  181. by one }
  182. s_pixel := (s_pixel and $1f) or ((s_pixel and $f800) shr 1) or
  183. ((s_pixel and $7c0) shr 1);
  184. PUint16(dest)^ := s_pixel;
  185. Dec(count);
  186. Inc(dest, 2); Inc(source, 2);
  187. end;
  188. { Now copy blocks of dwords }
  189. for i := 1 to count shr 1 do
  190. begin
  191. s_pixel := PUint32(source)^;
  192. { Leave blue untouched, mask red and shift by one, mask green and shift
  193. by one }
  194. s_pixel := (s_pixel and $001f001f) or ((s_pixel and $f800f800) shr 1) or
  195. ((s_pixel and $07c007c0) shr 1);
  196. PUint32(dest)^ := s_pixel;
  197. Inc(source, 4); Inc(dest, 4);
  198. end;
  199. if (count and 1) <> 0 then
  200. begin
  201. s_pixel := PUint16(source)^;
  202. { Leave blue untouched, mask red and shift by one, mask green and shift
  203. by one }
  204. s_pixel := (s_pixel and $1f) or ((s_pixel and $f800) shr 1) or
  205. ((s_pixel and $7c0) shr 1);
  206. PUint16(dest)^ := s_pixel;
  207. end;
  208. end;
  209. { TO 16 BIT BGR 555 }
  210. procedure ConvertP_16rgb565_16bgr555(source, dest: PUint8; count, inc_source: DWord); cdecl;
  211. var
  212. i: DWord;
  213. s_pixel: Uint32;
  214. begin
  215. { if we are not aligned to a dword, try and convert a single pixel }
  216. if (PtrUInt(dest) and $3) <> 0 then
  217. begin
  218. s_pixel := PUint16(source)^;
  219. { Shift red right by 11, mask green and shift right one, shift blue
  220. left ten }
  221. s_pixel := ((s_pixel and $f800) shr 11) or ((s_pixel and $7c0) shr 1) or
  222. ((s_pixel and $1f) shl 10);
  223. PUint16(dest)^ := s_pixel;
  224. Dec(count);
  225. Inc(dest, 2); Inc(source, 2);
  226. end;
  227. { Now copy blocks of dwords }
  228. for i := 1 to count shr 1 do
  229. begin
  230. s_pixel := PUint32(source)^;
  231. { Shift red right by 11, mask green and shift right one, shift blue
  232. left ten }
  233. s_pixel := ((s_pixel and $f800f800) shr 11) or
  234. ((s_pixel and $07c007c0) shr 1) or
  235. ((s_pixel and $001f001f) shl 10);
  236. PUint32(dest)^ := s_pixel;
  237. Inc(source, 4); Inc(dest, 4);
  238. end;
  239. if (count and 1) <> 0 then
  240. begin
  241. s_pixel := PUint16(source)^;
  242. { Shift red right by 11, mask green and shift right one, shift blue
  243. left ten }
  244. s_pixel := ((s_pixel and $f800) shr 11) or ((s_pixel and $7c0) shr 1) or
  245. ((s_pixel and $1f) shl 10);
  246. PUint16(dest)^ := s_pixel;
  247. end;
  248. end;
  249. { TO 8 BIT RGB 332 }
  250. procedure ConvertP_16rgb565_8rgb332(source, dest: PUint8; count, inc_source: DWord); cdecl;
  251. var
  252. s_block, d_block: Uint32;
  253. i: DWord;
  254. begin
  255. { Align to dword first }
  256. while (PtrUInt(dest) and $3) <> 0 do
  257. begin
  258. s_block := PUint16(source)^;
  259. s_block := ((s_block and $e000) shr 8) or ((s_block and $0700) shr 6) or
  260. ((s_block and $18) shr 3);
  261. dest^ := s_block;
  262. Dec(count);
  263. if count = 0 then
  264. exit;
  265. Inc(source, 2);
  266. Inc(dest);
  267. end;
  268. { Write blocks of four pixels }
  269. for i := 1 to count shr 2 do
  270. begin
  271. { Read and process first two pixels }
  272. s_block := PUint32(source)^;
  273. d_block := ((s_block and $e000e000) shr 8) or
  274. ((s_block and $07000700) shr 6) or
  275. ((s_block and $00180018) shr 3);
  276. d_block := (d_block and $ff) or ((d_block and $ff0000) shr 8);
  277. { and the second two }
  278. s_block := (PUint32(source)+1)^;
  279. s_block := ((s_block and $e000e000) shr 8) or
  280. ((s_block and $07000700) shr 6) or
  281. ((s_block and $00180018) shr 3);
  282. s_block := (s_block and $ff) or ((s_block and $ff0000) shr 8);
  283. { Put it all in one dword and write it }
  284. d_block := (d_block shl DWORD_SMALLINT0_SHL) or (s_block shl DWORD_SMALLINT1_SHL);
  285. PUint32(dest)^ := d_block;
  286. Inc(source, 8);
  287. Inc(dest, 4);
  288. end;
  289. { Clean up remaining pixels }
  290. count := count and 3;
  291. while count > 0 do
  292. begin
  293. Dec(count);
  294. s_block := PUint16(source)^;
  295. dest^ := ((s_block and $e000) shr 8) or ((s_block and $0700) shr 6) or
  296. ((s_block and $18) shr 3);
  297. Inc(dest);
  298. Inc(source, 2);
  299. end;
  300. end;
  301. { -------------------------------------------------------------------------
  302. STRETCH CONVERTERS
  303. ------------------------------------------------------------------------- }
  304. procedure ConvertP_16rgb565_32rgb888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  305. var
  306. x: DWord;
  307. p: Uint32;
  308. begin
  309. x := 0;
  310. repeat
  311. p := (((PUint16(source) + (x shr 16))^ and $f800) shl 8) or
  312. (((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
  313. (((PUint16(source) + (x shr 16))^ and $1f) shl 3) or $30103;
  314. Inc(x, inc_source);
  315. PUint32(dest)^ := p;
  316. Inc(dest, 4);
  317. Dec(count);
  318. until count = 0;
  319. end;
  320. procedure ConvertP_16rgb565_32bgr888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  321. var
  322. d_pixel: Uint32;
  323. x: DWord;
  324. begin
  325. x := 0;
  326. repeat
  327. d_pixel := (PUint16(source) + (x shr 16))^;
  328. d_pixel := ((d_pixel and $f800) shr 8) or ((d_pixel and $7e0) shl 5) or
  329. ((d_pixel and $1f) shl 19) or $30103;
  330. PUint32(dest)^ := d_pixel;
  331. Inc(dest, 4);
  332. Inc(x, inc_source);
  333. Dec(count);
  334. until count = 0;
  335. end;
  336. procedure ConvertP_16rgb565_32rgba888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  337. var
  338. x: DWord;
  339. p: Uint32;
  340. begin
  341. x := 0;
  342. repeat
  343. p := (((PUint16(source) + (x shr 16))^ and $f800) shl (8+8)) or
  344. (((PUint16(source) + (x shr 16))^ and $7e0) shl (5+8)) or
  345. (((PUint16(source) + (x shr 16))^ and $1f) shl (3+8)) or $30103ff;
  346. Inc(x, inc_source);
  347. PUint32(dest)^ := p;
  348. Inc(dest, 4);
  349. Dec(count);
  350. until count = 0;
  351. end;
  352. procedure ConvertP_16rgb565_32bgra888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  353. var
  354. d_pixel: Uint32;
  355. x: DWord;
  356. begin
  357. x := 0;
  358. repeat
  359. d_pixel := (PUint16(source) + (x shr 16))^;
  360. d_pixel := ((d_pixel and $f800) {Shr 8}) or ((d_pixel and $7e0) shl (5+8)) or
  361. ((d_pixel and $1f) shl (19+8)) or $30103ff;
  362. PUint32(dest)^ := d_pixel;
  363. Inc(dest, 4);
  364. Inc(x, inc_source);
  365. Dec(count);
  366. until count = 0;
  367. end;
  368. procedure ConvertP_16rgb565_24rgb888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  369. var
  370. x: DWord;
  371. p1, p2, p3, p4: DWord;
  372. c: DWord;
  373. begin
  374. x := 0;
  375. while (PtrUInt(dest) and 3) <> 0 do
  376. begin
  377. p1 := (((PUint16(source) + (x shr 16))^ and $f800) shl 8) or
  378. (((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
  379. (((PUint16(source) + (x shr 16))^ and $1f) shl 3) or $30103;
  380. (dest + B_24)^ := p1 and $FF;
  381. (dest + G_24)^ := (p1 shr 8) and $FF;
  382. (dest + R_24)^ := p1 shr 16;
  383. Inc(dest, 3);
  384. Inc(x, inc_source);
  385. Dec(count);
  386. if count = 0 then
  387. exit;
  388. end;
  389. c := count shr 2;
  390. while c > 0 do
  391. begin
  392. p1 := (PUint16(source) + (x shr 16))^;
  393. p2 := (PUint16(source) + ((x + inc_source) shr 16))^;
  394. p3 := (PUint16(source) + ((x + 2*inc_source) shr 16))^;
  395. p4 := (PUint16(source) + ((x + 3*inc_source) shr 16))^;
  396. {$IFDEF FPC_LITTLE_ENDIAN}
  397. PUint32(dest + 0)^ := ((p2 and $001F) shl 27) or ((p1 and $F800) shl 8) or ((p1 and $07E0) shl 5) or ((p1 and $001F) shl 3) or $03030103;
  398. PUint32(dest + 4)^ := ((p3 and $07E0) shl 21) or ((p3 and $001F) shl 19) or (p2 and $F800) or ((p2 and $07E0) shr 3) or $01030301;
  399. PUint32(dest + 8)^ := ((p4 and $F800) shl 16) or ((p4 and $07E0) shl 13) or ((p4 and $001F) shl 11) or ((p3 and $F800) shr 8) or $03010303;
  400. {$ELSE FPC_LITTLE_ENDIAN}
  401. PUint32(dest + 0)^ := ((p1 and $F800) shl 16) or ((p1 and $07E0) shl 13) or ((p1 and $001F) shl 11) or ((p2 and $F800) shr 8) or $03010303;
  402. PUint32(dest + 4)^ := ((p2 and $07E0) shl 21) or ((p2 and $001F) shl 19) or (p3 and $F800) or ((p3 and $07E0) shr 3) or $01030301;
  403. PUint32(dest + 8)^ := ((p3 and $001F) shl 27) or ((p4 and $F800) shl 8) or ((p4 and $07E0) shl 5) or ((p4 and $001F) shl 3) or $03030103;
  404. {$ENDIF FPC_LITTLE_ENDIAN}
  405. Inc(x, 4*inc_source);
  406. Inc(dest, 12);
  407. Dec(c);
  408. end;
  409. count := count and 3;
  410. while count > 0 do
  411. begin
  412. p1 := (((PUint16(source) + (x shr 16))^ and $f800) shl 8) or
  413. (((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
  414. (((PUint16(source) + (x shr 16))^ and $1f) shl 3) or $30103;
  415. (dest + B_24)^ := p1 and $FF;
  416. (dest + G_24)^ := (p1 shr 8) and $FF;
  417. (dest + R_24)^ := p1 shr 16;
  418. Inc(dest, 3);
  419. Inc(x, inc_source);
  420. Dec(count);
  421. end;
  422. end;
  423. procedure ConvertP_16rgb565_24bgr888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  424. var
  425. x: DWord;
  426. p1, p2, p3, p4: DWord;
  427. c: DWord;
  428. begin
  429. x := 0;
  430. while (PtrUInt(dest) and 3) <> 0 do
  431. begin
  432. p1 := (((PUint16(source) + (x shr 16))^ and $f800) shr 8) or
  433. (((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
  434. (((PUint16(source) + (x shr 16))^ and $1f) shl 19) or $30103;
  435. (dest + B_24)^ := p1 and $FF;
  436. (dest + G_24)^ := (p1 shr 8) and $FF;
  437. (dest + R_24)^ := p1 shr 16;
  438. Inc(dest, 3);
  439. Inc(x, inc_source);
  440. Dec(count);
  441. if count = 0 then
  442. exit;
  443. end;
  444. c := count shr 2;
  445. while c > 0 do
  446. begin
  447. p1 := (PUint16(source) + (x shr 16))^;
  448. p2 := (PUint16(source) + ((x + inc_source) shr 16))^;
  449. p3 := (PUint16(source) + ((x + 2*inc_source) shr 16))^;
  450. p4 := (PUint16(source) + ((x + 3*inc_source) shr 16))^;
  451. {$IFDEF FPC_LITTLE_ENDIAN}
  452. PUint32(dest + 0)^ := ((p2 and $F800) shl 16) or ((p1 and $001F) shl 19) or ((p1 and $07E0) shl 5) or ((p1 and $F800) shr 8) or $03030103;
  453. PUint32(dest + 4)^ := ((p3 and $07E0) shl 21) or ((p3 and $F800) shl 8) or ((p2 and $001F) shl 11) or ((p2 and $07E0) shr 3) or $01030301;
  454. PUint32(dest + 8)^ := ((p4 and $001F) shl 27) or ((p4 and $07E0) shl 13) or (p4 and $F800) or ((p3 and $001F) shl 3) or $03010303;
  455. {$ELSE FPC_LITTLE_ENDIAN}
  456. PUint32(dest + 0)^ := ((p1 and $001F) shl 27) or ((p1 and $07E0) shl 13) or (p1 and $F800) or ((p2 and $001F) shl 3) or $03010303;
  457. PUint32(dest + 4)^ := ((p2 and $07E0) shl 21) or ((p2 and $F800) shl 8) or ((p3 and $001F) shl 11) or ((p3 and $07E0) shr 3) or $01030301;
  458. PUint32(dest + 8)^ := ((p3 and $F800) shl 16) or ((p4 and $001F) shl 19) or ((p4 and $07E0) shl 5) or ((p4 and $F800) shr 8) or $03030103;
  459. {$ENDIF FPC_LITTLE_ENDIAN}
  460. Inc(x, 4*inc_source);
  461. Inc(dest, 12);
  462. Dec(c);
  463. end;
  464. count := count and 3;
  465. while count > 0 do
  466. begin
  467. p1 := (((PUint16(source) + (x shr 16))^ and $f800) shr 8) or
  468. (((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
  469. (((PUint16(source) + (x shr 16))^ and $1f) shl 19) or $30103;
  470. (dest + B_24)^ := p1 and $FF;
  471. (dest + G_24)^ := (p1 shr 8) and $FF;
  472. (dest + R_24)^ := p1 shr 16;
  473. Inc(dest, 3);
  474. Inc(x, inc_source);
  475. Dec(count);
  476. end;
  477. end;
  478. procedure ConvertP_16rgb565_16bgr565_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  479. var
  480. x, c: DWord;
  481. p: Uint32;
  482. begin
  483. x := 0;
  484. { if we are not aligned to a dword, try and convert a single pixel }
  485. if (PtrUInt(dest) and $3) <> 0 then
  486. begin
  487. { Swap r and b, leave g untouched }
  488. PUint16(dest)^ := ((PUint16(source) + (x shr 16))^ shr 11) or
  489. ((PUint16(source) + (x shr 16))^ and $7e0) or
  490. (((PUint16(source) + (x shr 16))^ shl 11) and $f800);
  491. Inc(x, inc_source);
  492. Inc(dest, 2);
  493. Dec(count);
  494. end;
  495. c := count shr 1;
  496. while c <> 0 do
  497. begin
  498. Dec(c);
  499. { Swap r and b, leave g untouched }
  500. p := (((PUint16(source) + (x shr 16))^ shr 11) or
  501. ((PUint16(source) + (x shr 16))^ and $7e0) or
  502. (((PUint16(source) + (x shr 16))^ shl 11) and $f800)) shl DWORD_SMALLINT0_SHL;
  503. Inc(x, inc_source);
  504. p := p or ((((PUint16(source) + (x shr 16))^ shr 11) or
  505. ((PUint16(source) + (x shr 16))^ and $7e0) or
  506. (((PUint16(source) + (x shr 16))^ shl 11) and $f800)) shl DWORD_SMALLINT1_SHL);
  507. Inc(x, inc_source);
  508. PUint32(dest)^ := p;
  509. Inc(dest, 4);
  510. end;
  511. if (count and 1) <> 0 then
  512. PUint16(dest)^ := ((PUint16(source) + (x shr 16))^ shr 11) or
  513. ((PUint16(source) + (x shr 16))^ and $7e0) or
  514. (((PUint16(source) + (x shr 16))^ shl 11) and $f800);
  515. end;
  516. procedure ConvertP_16rgb565_16rgb555_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  517. var
  518. x, c: DWord;
  519. p: Uint32;
  520. begin
  521. x := 0;
  522. { if we are not aligned to a dword, try and convert a single pixel }
  523. if (PtrUInt(dest) and $3) <> 0 then
  524. begin
  525. PUint16(dest)^ := (((PUint16(source) + (x shr 16))^ and $f800) shr 1) or
  526. (((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
  527. ((PUint16(source) + (x shr 16))^ and $1f);
  528. Inc(dest, 2);
  529. Inc(x, inc_source);
  530. Dec(count);
  531. end;
  532. c := count shr 1;
  533. while c <> 0 do
  534. begin
  535. Dec(c);
  536. { Leave blue untouched, mask red and shift by one, mask green and shift
  537. by one }
  538. p := ((((PUint16(source) + (x shr 16))^ and $f800) shr 1) or
  539. (((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
  540. ((PUint16(source) + (x shr 16))^ and $1f)) shl DWORD_SMALLINT0_SHL;
  541. Inc(x, inc_source);
  542. p := p or (((((PUint16(source) + (x shr 16))^ and $f800) shr 1) or
  543. (((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
  544. ((PUint16(source) + (x shr 16))^ and $1f)) shl DWORD_SMALLINT1_SHL);
  545. Inc(x, inc_source);
  546. PUint32(dest)^ := p;
  547. Inc(dest, 4);
  548. end;
  549. if (count and 1) <> 0 then
  550. PUint16(dest)^ := (((PUint16(source) + (x shr 16))^ and $f800) shr 1) or
  551. (((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
  552. ((PUint16(source) + (x shr 16))^ and $1f);
  553. end;
  554. procedure ConvertP_16rgb565_16bgr555_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  555. var
  556. x, c: DWord;
  557. p: Uint32;
  558. begin
  559. x := 0;
  560. { if we are not aligned to a dword, try and convert a single pixel }
  561. if (PtrUInt(dest) and $3) <> 0 then
  562. begin
  563. PUint16(dest)^ := (((PUint16(source) + (x shr 16))^ and $f800) shr 11) or
  564. (((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
  565. (((PUint16(source) + (x shr 16))^ and $1f) shl 10);
  566. Inc(dest, 2);
  567. Inc(x, inc_source);
  568. Dec(count);
  569. end;
  570. c := count shr 1;
  571. while c <> 0 do
  572. begin
  573. Dec(c);
  574. p := ((((PUint16(source) + (x shr 16))^ and $f800) shr 11) or
  575. (((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
  576. (((PUint16(source) + (x shr 16))^ and $1f) shl 10)) shl DWORD_SMALLINT0_SHL;
  577. Inc(x, inc_source);
  578. p := p or (((((PUint16(source) + (x shr 16))^ and $f800) shr 11) or
  579. (((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
  580. (((PUint16(source) + (x shr 16))^ and $1f) shl 10)) shl DWORD_SMALLINT1_SHL);
  581. Inc(x, inc_source);
  582. PUint32(dest)^ := p;
  583. Inc(dest, 4);
  584. end;
  585. if (count and 1) <> 0 then
  586. PUint16(dest)^ := (((PUint16(source) + (x shr 16))^ and $f800) shr 11) or
  587. (((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
  588. (((PUint16(source) + (x shr 16))^ and $1f) shl 10);
  589. end;
  590. procedure ConvertP_16rgb565_8rgb332_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
  591. var
  592. x, c: DWord;
  593. p: Uint32;
  594. begin
  595. x := 0;
  596. { Write single pixels until the destination address is aligned mod 4 }
  597. while (PtrUInt(dest) and $3) <> 0 do
  598. begin
  599. dest^ := (((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
  600. (((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
  601. (((PUint16(source) + (x shr 16))^ shr 3) and $3);
  602. Inc(x, inc_source);
  603. Inc(dest);
  604. Dec(count);
  605. if count = 0 then
  606. exit;
  607. end;
  608. {* Write blocks of four pixels now }
  609. c := count shr 2;
  610. while c <> 0 do
  611. begin
  612. Dec(c);
  613. p := ((((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
  614. (((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
  615. (((PUint16(source) + (x shr 16))^ shr 3) and $3)) shl DWORD_BYTE0_SHL;
  616. Inc(x, inc_source);
  617. p := p or
  618. (((((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
  619. (((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
  620. (((PUint16(source) + (x shr 16))^ shr 3) and $3)) shl DWORD_BYTE1_SHL);
  621. Inc(x, inc_source);
  622. p := p or
  623. (((((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
  624. (((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
  625. (((PUint16(source) + (x shr 16))^ shr 3) and $3)) shl DWORD_BYTE2_SHL);
  626. Inc(x, inc_source);
  627. p := p or
  628. (((((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
  629. (((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
  630. (((PUint16(source) + (x shr 16))^ shr 3) and $3)) shl DWORD_BYTE3_SHL);
  631. Inc(x, inc_source);
  632. PUint32(dest)^ := p;
  633. Inc(dest, 4);
  634. end;
  635. { Write up to three trailing pixels }
  636. c := count and $3;
  637. while c <> 0 do
  638. begin
  639. Dec(c);
  640. dest^ := (((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
  641. (((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
  642. (((PUint16(source) + (x shr 16))^ shr 3) and $3);
  643. Inc(x, inc_source);
  644. Inc(dest);
  645. end;
  646. end;