PageRenderTime 182ms CodeModel.GetById 13ms app.highlight 156ms RepoModel.GetById 3ms app.codeStats 1ms

/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
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;