2
* This file is part of the Scale2x project.
4
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
* This file contains a C and MMX implementation of the Scale2x effect.
24
* You can find an high level description of the effect at :
26
* http://scale2x.sourceforge.net/
28
* Alternatively at the previous license terms, you are allowed to use this
29
* code in your program with these conditions:
30
* - the program is not used in commercial activities.
31
* - the whole source code of the program is released with the binary.
32
* - derivative works of the program are allowed.
35
#include "../../types.h" //mbg merge 7/17/06 added to get rid of __restrict__ in msvc
40
/***************************************************************************/
41
/* Scale2x C implementation */
43
static inline void scale2x_8_def_single(scale2x_uint8* __restrict__ dst, const scale2x_uint8* __restrict__ src0, const scale2x_uint8* __restrict__ src1, const scale2x_uint8* __restrict__ src2, unsigned count)
49
if (src1[1] == src0[0] && src2[0] != src0[0])
61
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
62
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
63
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
77
if (src1[-1] == src0[0] && src2[0] != src0[0])
84
static inline void scale2x_16_def_single(scale2x_uint16* __restrict__ dst, const scale2x_uint16* __restrict__ src0, const scale2x_uint16* __restrict__ src1, const scale2x_uint16* __restrict__ src2, unsigned count)
90
if (src1[1] == src0[0] && src2[0] != src0[0])
102
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
103
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
104
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
118
if (src1[-1] == src0[0] && src2[0] != src0[0])
125
static inline void scale2x_32_def_single(scale2x_uint32* __restrict__ dst, const scale2x_uint32* __restrict__ src0, const scale2x_uint32* __restrict__ src1, const scale2x_uint32* __restrict__ src2, unsigned count)
131
if (src1[1] == src0[0] && src2[0] != src0[0])
143
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
144
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
145
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
159
if (src1[-1] == src0[0] && src2[0] != src0[0])
167
* Scale by a factor of 2 a row of pixels of 8 bits.
168
* The function is implemented in C.
169
* The pixels over the left and right borders are assumed of the same color of
170
* the pixels on the border.
171
* \param src0 Pointer at the first pixel of the previous row.
172
* \param src1 Pointer at the first pixel of the current row.
173
* \param src2 Pointer at the first pixel of the next row.
174
* \param count Length in pixels of the src0, src1 and src2 rows.
175
* It must be at least 2.
176
* \param dst0 First destination row, double length in pixels.
177
* \param dst1 Second destination row, double length in pixels.
179
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
183
scale2x_8_def_single(dst0, src0, src1, src2, count);
184
scale2x_8_def_single(dst1, src2, src1, src0, count);
188
* Scale by a factor of 2 a row of pixels of 16 bits.
189
* This function operates like scale2x_8_def() but for 16 bits pixels.
190
* \param src0 Pointer at the first pixel of the previous row.
191
* \param src1 Pointer at the first pixel of the current row.
192
* \param src2 Pointer at the first pixel of the next row.
193
* \param count Length in pixels of the src0, src1 and src2 rows.
194
* It must be at least 2.
195
* \param dst0 First destination row, double length in pixels.
196
* \param dst1 Second destination row, double length in pixels.
198
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
202
scale2x_16_def_single(dst0, src0, src1, src2, count);
203
scale2x_16_def_single(dst1, src2, src1, src0, count);
207
* Scale by a factor of 2 a row of pixels of 32 bits.
208
* This function operates like scale2x_8_def() but for 32 bits pixels.
209
* \param src0 Pointer at the first pixel of the previous row.
210
* \param src1 Pointer at the first pixel of the current row.
211
* \param src2 Pointer at the first pixel of the next row.
212
* \param count Length in pixels of the src0, src1 and src2 rows.
213
* It must be at least 2.
214
* \param dst0 First destination row, double length in pixels.
215
* \param dst1 Second destination row, double length in pixels.
217
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
221
scale2x_32_def_single(dst0, src0, src1, src2, count);
222
scale2x_32_def_single(dst1, src2, src1, src0, count);
225
/***************************************************************************/
226
/* Scale2x MMX implementation */
228
#if defined(__GNUC__) && defined(__i386__)
231
* Apply the Scale2x effect at a single row.
232
* This function must be called only by the other scale2x functions.
234
* Considering the pixel map :
240
* this functions compute 2 new pixels in substitution of the source pixel E
245
* with these variables :
249
* ¤t_right -> F
250
* ¤t_upper -> B
251
* ¤t_lower -> H
253
* %0 -> current_upper
255
* %2 -> current_lower
259
* %mm0 -> *current_left
260
* %mm1 -> *current_next
265
* %mm6 -> *current_upper
268
static inline void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
271
assert(count % 8 == 0);
273
/* always do the first and last run */
276
__asm__ __volatile__(
278
/* set the current, current_pre, current_next registers */
279
"movq 0(%1), %%mm0\n"
280
"movq 0(%1), %%mm7\n"
281
"movq 8(%1), %%mm1\n"
285
"movq %%mm7, %%mm2\n"
286
"movq %%mm7, %%mm3\n"
295
/* compute the upper-left pixel for dst on %%mm2 */
296
/* compute the upper-right pixel for dst on %%mm4 */
297
"movq %%mm0, %%mm2\n"
298
"movq %%mm1, %%mm4\n"
299
"movq %%mm0, %%mm3\n"
300
"movq %%mm1, %%mm5\n"
301
"pcmpeqb %%mm6, %%mm2\n"
302
"pcmpeqb %%mm6, %%mm4\n"
303
"pcmpeqb (%2), %%mm3\n"
304
"pcmpeqb (%2), %%mm5\n"
305
"pandn %%mm2, %%mm3\n"
306
"pandn %%mm4, %%mm5\n"
307
"movq %%mm0, %%mm2\n"
308
"movq %%mm1, %%mm4\n"
309
"pcmpeqb %%mm1, %%mm2\n"
310
"pcmpeqb %%mm0, %%mm4\n"
311
"pandn %%mm3, %%mm2\n"
312
"pandn %%mm5, %%mm4\n"
313
"movq %%mm2, %%mm3\n"
314
"movq %%mm4, %%mm5\n"
315
"pand %%mm6, %%mm2\n"
316
"pand %%mm6, %%mm4\n"
317
"pandn %%mm7, %%mm3\n"
318
"pandn %%mm7, %%mm5\n"
323
"movq %%mm2, %%mm3\n"
324
"punpcklbw %%mm4, %%mm2\n"
325
"punpckhbw %%mm4, %%mm3\n"
327
"movq %%mm3, 8(%3)\n"
341
/* set the current, current_pre, current_next registers */
342
"movq -8(%1), %%mm0\n"
344
"movq 8(%1), %%mm1\n"
347
"movq %%mm7, %%mm2\n"
348
"movq %%mm7, %%mm3\n"
357
/* compute the upper-left pixel for dst on %%mm2 */
358
/* compute the upper-right pixel for dst on %%mm4 */
359
"movq %%mm0, %%mm2\n"
360
"movq %%mm1, %%mm4\n"
361
"movq %%mm0, %%mm3\n"
362
"movq %%mm1, %%mm5\n"
363
"pcmpeqb %%mm6, %%mm2\n"
364
"pcmpeqb %%mm6, %%mm4\n"
365
"pcmpeqb (%2), %%mm3\n"
366
"pcmpeqb (%2), %%mm5\n"
367
"pandn %%mm2, %%mm3\n"
368
"pandn %%mm4, %%mm5\n"
369
"movq %%mm0, %%mm2\n"
370
"movq %%mm1, %%mm4\n"
371
"pcmpeqb %%mm1, %%mm2\n"
372
"pcmpeqb %%mm0, %%mm4\n"
373
"pandn %%mm3, %%mm2\n"
374
"pandn %%mm5, %%mm4\n"
375
"movq %%mm2, %%mm3\n"
376
"movq %%mm4, %%mm5\n"
377
"pand %%mm6, %%mm2\n"
378
"pand %%mm6, %%mm4\n"
379
"pandn %%mm7, %%mm3\n"
380
"pandn %%mm7, %%mm5\n"
385
"movq %%mm2, %%mm3\n"
386
"punpcklbw %%mm4, %%mm2\n"
387
"punpckhbw %%mm4, %%mm3\n"
389
"movq %%mm3, 8(%3)\n"
402
/* set the current, current_pre, current_next registers */
405
"movq -8(%1), %%mm0\n"
409
"movq %%mm7, %%mm2\n"
410
"movq %%mm7, %%mm3\n"
419
/* compute the upper-left pixel for dst on %%mm2 */
420
/* compute the upper-right pixel for dst on %%mm4 */
421
"movq %%mm0, %%mm2\n"
422
"movq %%mm1, %%mm4\n"
423
"movq %%mm0, %%mm3\n"
424
"movq %%mm1, %%mm5\n"
425
"pcmpeqb %%mm6, %%mm2\n"
426
"pcmpeqb %%mm6, %%mm4\n"
427
"pcmpeqb (%2), %%mm3\n"
428
"pcmpeqb (%2), %%mm5\n"
429
"pandn %%mm2, %%mm3\n"
430
"pandn %%mm4, %%mm5\n"
431
"movq %%mm0, %%mm2\n"
432
"movq %%mm1, %%mm4\n"
433
"pcmpeqb %%mm1, %%mm2\n"
434
"pcmpeqb %%mm0, %%mm4\n"
435
"pandn %%mm3, %%mm2\n"
436
"pandn %%mm5, %%mm4\n"
437
"movq %%mm2, %%mm3\n"
438
"movq %%mm4, %%mm5\n"
439
"pand %%mm6, %%mm2\n"
440
"pand %%mm6, %%mm4\n"
441
"pandn %%mm7, %%mm3\n"
442
"pandn %%mm7, %%mm5\n"
447
"movq %%mm2, %%mm3\n"
448
"punpcklbw %%mm4, %%mm2\n"
449
"punpckhbw %%mm4, %%mm3\n"
451
"movq %%mm3, 8(%3)\n"
453
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
459
static inline void scale2x_16_mmx_single(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
462
assert(count % 4 == 0);
464
/* always do the first and last run */
467
__asm__ __volatile__(
469
/* set the current, current_pre, current_next registers */
470
"movq 0(%1), %%mm0\n"
471
"movq 0(%1), %%mm7\n"
472
"movq 8(%1), %%mm1\n"
476
"movq %%mm7, %%mm2\n"
477
"movq %%mm7, %%mm3\n"
486
/* compute the upper-left pixel for dst on %%mm2 */
487
/* compute the upper-right pixel for dst on %%mm4 */
488
"movq %%mm0, %%mm2\n"
489
"movq %%mm1, %%mm4\n"
490
"movq %%mm0, %%mm3\n"
491
"movq %%mm1, %%mm5\n"
492
"pcmpeqw %%mm6, %%mm2\n"
493
"pcmpeqw %%mm6, %%mm4\n"
494
"pcmpeqw (%2), %%mm3\n"
495
"pcmpeqw (%2), %%mm5\n"
496
"pandn %%mm2, %%mm3\n"
497
"pandn %%mm4, %%mm5\n"
498
"movq %%mm0, %%mm2\n"
499
"movq %%mm1, %%mm4\n"
500
"pcmpeqw %%mm1, %%mm2\n"
501
"pcmpeqw %%mm0, %%mm4\n"
502
"pandn %%mm3, %%mm2\n"
503
"pandn %%mm5, %%mm4\n"
504
"movq %%mm2, %%mm3\n"
505
"movq %%mm4, %%mm5\n"
506
"pand %%mm6, %%mm2\n"
507
"pand %%mm6, %%mm4\n"
508
"pandn %%mm7, %%mm3\n"
509
"pandn %%mm7, %%mm5\n"
514
"movq %%mm2, %%mm3\n"
515
"punpcklwd %%mm4, %%mm2\n"
516
"punpckhwd %%mm4, %%mm3\n"
518
"movq %%mm3, 8(%3)\n"
532
/* set the current, current_pre, current_next registers */
533
"movq -8(%1), %%mm0\n"
535
"movq 8(%1), %%mm1\n"
538
"movq %%mm7, %%mm2\n"
539
"movq %%mm7, %%mm3\n"
548
/* compute the upper-left pixel for dst on %%mm2 */
549
/* compute the upper-right pixel for dst on %%mm4 */
550
"movq %%mm0, %%mm2\n"
551
"movq %%mm1, %%mm4\n"
552
"movq %%mm0, %%mm3\n"
553
"movq %%mm1, %%mm5\n"
554
"pcmpeqw %%mm6, %%mm2\n"
555
"pcmpeqw %%mm6, %%mm4\n"
556
"pcmpeqw (%2), %%mm3\n"
557
"pcmpeqw (%2), %%mm5\n"
558
"pandn %%mm2, %%mm3\n"
559
"pandn %%mm4, %%mm5\n"
560
"movq %%mm0, %%mm2\n"
561
"movq %%mm1, %%mm4\n"
562
"pcmpeqw %%mm1, %%mm2\n"
563
"pcmpeqw %%mm0, %%mm4\n"
564
"pandn %%mm3, %%mm2\n"
565
"pandn %%mm5, %%mm4\n"
566
"movq %%mm2, %%mm3\n"
567
"movq %%mm4, %%mm5\n"
568
"pand %%mm6, %%mm2\n"
569
"pand %%mm6, %%mm4\n"
570
"pandn %%mm7, %%mm3\n"
571
"pandn %%mm7, %%mm5\n"
576
"movq %%mm2, %%mm3\n"
577
"punpcklwd %%mm4, %%mm2\n"
578
"punpckhwd %%mm4, %%mm3\n"
580
"movq %%mm3, 8(%3)\n"
593
/* set the current, current_pre, current_next registers */
596
"movq -8(%1), %%mm0\n"
600
"movq %%mm7, %%mm2\n"
601
"movq %%mm7, %%mm3\n"
610
/* compute the upper-left pixel for dst on %%mm2 */
611
/* compute the upper-right pixel for dst on %%mm4 */
612
"movq %%mm0, %%mm2\n"
613
"movq %%mm1, %%mm4\n"
614
"movq %%mm0, %%mm3\n"
615
"movq %%mm1, %%mm5\n"
616
"pcmpeqw %%mm6, %%mm2\n"
617
"pcmpeqw %%mm6, %%mm4\n"
618
"pcmpeqw (%2), %%mm3\n"
619
"pcmpeqw (%2), %%mm5\n"
620
"pandn %%mm2, %%mm3\n"
621
"pandn %%mm4, %%mm5\n"
622
"movq %%mm0, %%mm2\n"
623
"movq %%mm1, %%mm4\n"
624
"pcmpeqw %%mm1, %%mm2\n"
625
"pcmpeqw %%mm0, %%mm4\n"
626
"pandn %%mm3, %%mm2\n"
627
"pandn %%mm5, %%mm4\n"
628
"movq %%mm2, %%mm3\n"
629
"movq %%mm4, %%mm5\n"
630
"pand %%mm6, %%mm2\n"
631
"pand %%mm6, %%mm4\n"
632
"pandn %%mm7, %%mm3\n"
633
"pandn %%mm7, %%mm5\n"
638
"movq %%mm2, %%mm3\n"
639
"punpcklwd %%mm4, %%mm2\n"
640
"punpckhwd %%mm4, %%mm3\n"
642
"movq %%mm3, 8(%3)\n"
644
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
650
static inline void scale2x_32_mmx_single(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
653
assert(count % 2 == 0);
655
/* always do the first and last run */
658
__asm__ __volatile__(
660
/* set the current, current_pre, current_next registers */
661
"movq 0(%1), %%mm0\n"
662
"movq 0(%1), %%mm7\n"
663
"movq 8(%1), %%mm1\n"
667
"movq %%mm7, %%mm2\n"
668
"movq %%mm7, %%mm3\n"
677
/* compute the upper-left pixel for dst on %%mm2 */
678
/* compute the upper-right pixel for dst on %%mm4 */
679
"movq %%mm0, %%mm2\n"
680
"movq %%mm1, %%mm4\n"
681
"movq %%mm0, %%mm3\n"
682
"movq %%mm1, %%mm5\n"
683
"pcmpeqd %%mm6, %%mm2\n"
684
"pcmpeqd %%mm6, %%mm4\n"
685
"pcmpeqd (%2), %%mm3\n"
686
"pcmpeqd (%2), %%mm5\n"
687
"pandn %%mm2, %%mm3\n"
688
"pandn %%mm4, %%mm5\n"
689
"movq %%mm0, %%mm2\n"
690
"movq %%mm1, %%mm4\n"
691
"pcmpeqd %%mm1, %%mm2\n"
692
"pcmpeqd %%mm0, %%mm4\n"
693
"pandn %%mm3, %%mm2\n"
694
"pandn %%mm5, %%mm4\n"
695
"movq %%mm2, %%mm3\n"
696
"movq %%mm4, %%mm5\n"
697
"pand %%mm6, %%mm2\n"
698
"pand %%mm6, %%mm4\n"
699
"pandn %%mm7, %%mm3\n"
700
"pandn %%mm7, %%mm5\n"
705
"movq %%mm2, %%mm3\n"
706
"punpckldq %%mm4, %%mm2\n"
707
"punpckhdq %%mm4, %%mm3\n"
709
"movq %%mm3, 8(%3)\n"
723
/* set the current, current_pre, current_next registers */
724
"movq -8(%1), %%mm0\n"
726
"movq 8(%1), %%mm1\n"
729
"movq %%mm7, %%mm2\n"
730
"movq %%mm7, %%mm3\n"
739
/* compute the upper-left pixel for dst on %%mm2 */
740
/* compute the upper-right pixel for dst on %%mm4 */
741
"movq %%mm0, %%mm2\n"
742
"movq %%mm1, %%mm4\n"
743
"movq %%mm0, %%mm3\n"
744
"movq %%mm1, %%mm5\n"
745
"pcmpeqd %%mm6, %%mm2\n"
746
"pcmpeqd %%mm6, %%mm4\n"
747
"pcmpeqd (%2), %%mm3\n"
748
"pcmpeqd (%2), %%mm5\n"
749
"pandn %%mm2, %%mm3\n"
750
"pandn %%mm4, %%mm5\n"
751
"movq %%mm0, %%mm2\n"
752
"movq %%mm1, %%mm4\n"
753
"pcmpeqd %%mm1, %%mm2\n"
754
"pcmpeqd %%mm0, %%mm4\n"
755
"pandn %%mm3, %%mm2\n"
756
"pandn %%mm5, %%mm4\n"
757
"movq %%mm2, %%mm3\n"
758
"movq %%mm4, %%mm5\n"
759
"pand %%mm6, %%mm2\n"
760
"pand %%mm6, %%mm4\n"
761
"pandn %%mm7, %%mm3\n"
762
"pandn %%mm7, %%mm5\n"
767
"movq %%mm2, %%mm3\n"
768
"punpckldq %%mm4, %%mm2\n"
769
"punpckhdq %%mm4, %%mm3\n"
771
"movq %%mm3, 8(%3)\n"
784
/* set the current, current_pre, current_next registers */
787
"movq -8(%1), %%mm0\n"
791
"movq %%mm7, %%mm2\n"
792
"movq %%mm7, %%mm3\n"
801
/* compute the upper-left pixel for dst on %%mm2 */
802
/* compute the upper-right pixel for dst on %%mm4 */
803
"movq %%mm0, %%mm2\n"
804
"movq %%mm1, %%mm4\n"
805
"movq %%mm0, %%mm3\n"
806
"movq %%mm1, %%mm5\n"
807
"pcmpeqd %%mm6, %%mm2\n"
808
"pcmpeqd %%mm6, %%mm4\n"
809
"pcmpeqd (%2), %%mm3\n"
810
"pcmpeqd (%2), %%mm5\n"
811
"pandn %%mm2, %%mm3\n"
812
"pandn %%mm4, %%mm5\n"
813
"movq %%mm0, %%mm2\n"
814
"movq %%mm1, %%mm4\n"
815
"pcmpeqd %%mm1, %%mm2\n"
816
"pcmpeqd %%mm0, %%mm4\n"
817
"pandn %%mm3, %%mm2\n"
818
"pandn %%mm5, %%mm4\n"
819
"movq %%mm2, %%mm3\n"
820
"movq %%mm4, %%mm5\n"
821
"pand %%mm6, %%mm2\n"
822
"pand %%mm6, %%mm4\n"
823
"pandn %%mm7, %%mm3\n"
824
"pandn %%mm7, %%mm5\n"
829
"movq %%mm2, %%mm3\n"
830
"punpckldq %%mm4, %%mm2\n"
831
"punpckhdq %%mm4, %%mm3\n"
833
"movq %%mm3, 8(%3)\n"
835
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
842
* Scale by a factor of 2 a row of pixels of 8 bits.
843
* This is a very fast MMX implementation.
844
* The implementation uses a combination of cmp/and/not operations to
845
* completly remove the need of conditional jumps. This trick give the
846
* major speed improvement.
847
* Also, using the 8 bytes MMX registers more than one pixel are computed
849
* Before calling this function you must ensure that the currenct CPU supports
850
* the MMX instruction set. After calling it you must be sure to call the EMMS
851
* instruction before any floating-point operation.
852
* The pixels over the left and right borders are assumed of the same color of
853
* the pixels on the border.
854
* \param src0 Pointer at the first pixel of the previous row.
855
* \param src1 Pointer at the first pixel of the current row.
856
* \param src2 Pointer at the first pixel of the next row.
857
* \param count Length in pixels of the src0, src1 and src2 rows. It must
858
* be at least 16 and a multiple of 8.
859
* \param dst0 First destination row, double length in pixels.
860
* \param dst1 Second destination row, double length in pixels.
862
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
864
if (count % 8 != 0 || count < 16) {
865
scale2x_8_def(dst0, dst1, src0, src1, src2, count);
868
assert(count % 8 == 0);
870
scale2x_8_mmx_single(dst0, src0, src1, src2, count);
871
scale2x_8_mmx_single(dst1, src2, src1, src0, count);
876
* Scale by a factor of 2 a row of pixels of 16 bits.
877
* This function operates like scale2x_8_mmx() but for 16 bits pixels.
878
* \param src0 Pointer at the first pixel of the previous row.
879
* \param src1 Pointer at the first pixel of the current row.
880
* \param src2 Pointer at the first pixel of the next row.
881
* \param count Length in pixels of the src0, src1 and src2 rows. It must
882
* be at least 8 and a multiple of 4.
883
* \param dst0 First destination row, double length in pixels.
884
* \param dst1 Second destination row, double length in pixels.
886
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
888
if (count % 4 != 0 || count < 8) {
889
scale2x_16_def(dst0, dst1, src0, src1, src2, count);
892
assert(count % 4 == 0);
894
scale2x_16_mmx_single(dst0, src0, src1, src2, count);
895
scale2x_16_mmx_single(dst1, src2, src1, src0, count);
900
* Scale by a factor of 2 a row of pixels of 32 bits.
901
* This function operates like scale2x_8_mmx() but for 32 bits pixels.
902
* \param src0 Pointer at the first pixel of the previous row.
903
* \param src1 Pointer at the first pixel of the current row.
904
* \param src2 Pointer at the first pixel of the next row.
905
* \param count Length in pixels of the src0, src1 and src2 rows. It must
906
* be at least 4 and a multiple of 2.
907
* \param dst0 First destination row, double length in pixels.
908
* \param dst1 Second destination row, double length in pixels.
910
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
912
if (count % 2 != 0 || count < 4) {
913
scale2x_32_def(dst0, dst1, src0, src1, src2, count);
916
assert(count % 2 == 0);
918
scale2x_32_mmx_single(dst0, src0, src1, src2, count);
919
scale2x_32_mmx_single(dst1, src2, src1, src0, count);