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