Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
O
openjazz
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PocketInsanity
openjazz
Commits
91791324
Commit
91791324
authored
Mar 26, 2010
by
alistert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed src/scale2x, is now in src/io/gfx/scale2x
parent
9d436013
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
0 additions
and
3201 deletions
+0
-3201
getopt.cpp
src/scale2x/getopt.cpp
+0
-113
pixel.cpp
src/scale2x/pixel.cpp
+0
-68
pixel.h
src/scale2x/pixel.h
+0
-30
portable.h
src/scale2x/portable.h
+0
-46
scale2x.cpp
src/scale2x/scale2x.cpp
+0
-1462
scale2x.h
src/scale2x/scale2x.h
+0
-70
scale3x.cpp
src/scale2x/scale3x.cpp
+0
-704
scale3x.h
src/scale2x/scale3x.h
+0
-35
scalebit.cpp
src/scale2x/scalebit.cpp
+0
-511
scalebit.h
src/scale2x/scalebit.h
+0
-45
simple2x.cpp
src/scale2x/simple2x.cpp
+0
-117
No files found.
src/scale2x/getopt.cpp
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Advance project.
*
* Copyright (C) 2002 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#if !HAVE_GETOPT
/* This source is extracted from the DJGPP LIBC library */
#define unconst(var, type) ((type)(var))
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
#include <stdio.h>
int
opterr
=
1
,
optind
=
1
,
optopt
=
0
;
char
*
optarg
=
0
;
#define BADCH (int)'?'
#define EMSG ""
int
getopt
(
int
nargc
,
char
*
const
nargv
[],
char
*
ostr
)
{
static
const
char
*
place
=
EMSG
;
/* option letter processing */
char
*
oli
;
/* option letter list index */
char
*
p
;
if
(
!*
place
)
{
if
(
optind
>=
nargc
||
*
(
place
=
nargv
[
optind
])
!=
'-'
)
{
place
=
EMSG
;
return
(
EOF
);
}
if
(
place
[
1
]
&&
*++
place
==
'-'
)
{
++
optind
;
place
=
EMSG
;
return
(
EOF
);
}
}
if
((
optopt
=
(
int
)
*
place
++
)
==
(
int
)
':'
||
!
(
oli
=
strchr
(
ostr
,
optopt
)))
{
/*
* if the user didn't specify '-' as an option,
* assume it means EOF.
*/
if
(
optopt
==
(
int
)
'-'
)
return
EOF
;
if
(
!*
place
)
++
optind
;
if
(
opterr
)
{
if
(
!
(
p
=
strrchr
(
*
nargv
,
'/'
)))
p
=
*
nargv
;
else
++
p
;
fprintf
(
stderr
,
"%s: illegal option -- %c
\n
"
,
p
,
optopt
);
}
return
BADCH
;
}
if
(
*++
oli
!=
':'
)
{
/* don't need argument */
optarg
=
NULL
;
if
(
!*
place
)
++
optind
;
}
else
{
/* need an argument */
if
(
*
place
)
/* no white space */
optarg
=
unconst
(
place
,
char
*
);
else
if
(
nargc
<=
++
optind
)
{
/* no arg */
place
=
EMSG
;
if
(
!
(
p
=
strrchr
(
*
nargv
,
'/'
)))
p
=
*
nargv
;
else
++
p
;
if
(
opterr
)
fprintf
(
stderr
,
"%s: option requires an argument -- %c
\n
"
,
p
,
optopt
);
return
BADCH
;
}
else
/* white space */
optarg
=
nargv
[
optind
];
place
=
EMSG
;
++
optind
;
}
return
optopt
;
/* dump back option letter */
}
#endif
src/scale2x/pixel.cpp
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2003 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "pixel.h"
pixel_t
pixel_get
(
int
x
,
int
y
,
const
unsigned
char
*
pix
,
unsigned
slice
,
unsigned
pixel
,
unsigned
dx
,
unsigned
dy
,
int
opt_tes
)
{
const
unsigned
char
*
p
;
unsigned
i
;
pixel_t
v
;
if
(
opt_tes
)
{
if
(
x
<
0
)
x
+=
dx
;
if
(
x
>=
dx
)
x
-=
dx
;
if
(
y
<
0
)
y
+=
dy
;
if
(
y
>=
dy
)
y
-=
dy
;
}
else
{
if
(
x
<
0
)
x
=
0
;
if
(
x
>=
dx
)
x
=
dx
-
1
;
if
(
y
<
0
)
y
=
0
;
if
(
y
>=
dy
)
y
=
dy
-
1
;
}
p
=
pix
+
(
y
*
slice
)
+
(
x
*
pixel
);
v
=
0
;
for
(
i
=
0
;
i
<
pixel
;
++
i
)
v
|=
((
pixel_t
)
p
[
i
])
<<
(
i
*
8
);
return
v
;
}
void
pixel_put
(
int
x
,
int
y
,
unsigned
char
*
pix
,
unsigned
slice
,
unsigned
pixel
,
unsigned
dx
,
unsigned
dy
,
pixel_t
v
)
{
unsigned
char
*
p
;
unsigned
i
;
p
=
pix
+
(
y
*
slice
)
+
(
x
*
pixel
);
for
(
i
=
0
;
i
<
pixel
;
++
i
)
{
p
[
i
]
=
v
>>
(
i
*
8
);
}
}
src/scale2x/pixel.h
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2003 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __PIXEL_H
#define __PIXEL_H
typedef
unsigned
long
long
pixel_t
;
pixel_t
pixel_get
(
int
x
,
int
y
,
const
unsigned
char
*
pix
,
unsigned
slice
,
unsigned
pixel
,
unsigned
dx
,
unsigned
dy
,
int
opt_tes
);
void
pixel_put
(
int
x
,
int
y
,
unsigned
char
*
pix
,
unsigned
slice
,
unsigned
pixel
,
unsigned
dx
,
unsigned
dy
,
pixel_t
v
);
#endif
src/scale2x/portable.h
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __PORTABLE_H
#define __PORTABLE_H
#if HAVE_CONFIG_H
#include <config.h>
#endif
/* ------------------------------------------------------------------------ */
/* getopt */
#if HAVE_GETOPT_H
#include <getopt.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if !HAVE_GETOPT
int
getopt
(
int
argc
,
char
*
const
*
argv
,
const
char
*
options
);
extern
char
*
optarg
;
extern
int
optind
,
opterr
,
optopt
;
#endif
#endif
src/scale2x/scale2x.cpp
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file contains a C and MMX implementation of the Scale2x effect.
*
* You can find an high level description of the effect at :
*
* http://scale2x.sourceforge.net/
*
* Alternatively at the previous license terms, you are allowed to use this
* code in your program with these conditions:
* - the program is not used in commercial activities.
* - the whole source code of the program is released with the binary.
* - derivative works of the program are allowed.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "scale2x.h"
#include <assert.h>
/***************************************************************************/
/* Scale2x C implementation */
/**
* Define the macro USE_SCALE_RANDOMWRITE to enable
* an optimized version which writes memory in random order.
* This version is a little faster if you write in system memory.
* But it's a lot slower if you write in video memory.
* So, enable it only if you are sure to never write directly in video memory.
*/
/* #define USE_SCALE_RANDOMWRITE */
static
inline
void
scale2x_8_def_whole
(
scale2x_uint8
*
restrict
dst0
,
scale2x_uint8
*
restrict
dst1
,
const
scale2x_uint8
*
restrict
src0
,
const
scale2x_uint8
*
restrict
src1
,
const
scale2x_uint8
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
0
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
2
;
dst1
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
2
;
dst1
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
}
static
inline
void
scale2x_8_def_border
(
scale2x_uint8
*
restrict
dst
,
const
scale2x_uint8
*
restrict
src0
,
const
scale2x_uint8
*
restrict
src1
,
const
scale2x_uint8
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
}
static
inline
void
scale2x_8_def_center
(
scale2x_uint8
*
restrict
dst
,
const
scale2x_uint8
*
restrict
src0
,
const
scale2x_uint8
*
restrict
src1
,
const
scale2x_uint8
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
}
static
inline
void
scale2x_16_def_whole
(
scale2x_uint16
*
restrict
dst0
,
scale2x_uint16
*
restrict
dst1
,
const
scale2x_uint16
*
restrict
src0
,
const
scale2x_uint16
*
restrict
src1
,
const
scale2x_uint16
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
0
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
2
;
dst1
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
2
;
dst1
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
}
static
inline
void
scale2x_16_def_border
(
scale2x_uint16
*
restrict
dst
,
const
scale2x_uint16
*
restrict
src0
,
const
scale2x_uint16
*
restrict
src1
,
const
scale2x_uint16
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
}
static
inline
void
scale2x_16_def_center
(
scale2x_uint16
*
restrict
dst
,
const
scale2x_uint16
*
restrict
src0
,
const
scale2x_uint16
*
restrict
src1
,
const
scale2x_uint16
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
}
static
inline
void
scale2x_32_def_whole
(
scale2x_uint32
*
restrict
dst0
,
scale2x_uint32
*
restrict
dst1
,
const
scale2x_uint32
*
restrict
src0
,
const
scale2x_uint32
*
restrict
src1
,
const
scale2x_uint32
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
0
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
2
;
dst1
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
2
;
dst1
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst0
[
1
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst1
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
]
==
src2
[
0
]
?
src2
[
0
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
}
}
static
inline
void
scale2x_32_def_border
(
scale2x_uint32
*
restrict
dst
,
const
scale2x_uint32
*
restrict
src0
,
const
scale2x_uint32
*
restrict
src1
,
const
scale2x_uint32
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
]
==
src0
[
0
]
?
src0
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
}
static
inline
void
scale2x_32_def_center
(
scale2x_uint32
*
restrict
dst
,
const
scale2x_uint32
*
restrict
src0
,
const
scale2x_uint32
*
restrict
src1
,
const
scale2x_uint32
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
2
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
}
}
/**
* Scale by a factor of 2 a row of pixels of 8 bits.
* The function is implemented in C.
* The pixels over the left and right borders are assumed of the same color of
* the pixels on the border.
* Note that the implementation is optimized to write data sequentially to
* maximize the bandwidth on video memory.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void
scale2x_8_def
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_8_def_whole
(
dst0
,
dst1
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_8_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_border
(
dst1
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 2 a row of pixels of 16 bits.
* This function operates like scale2x_8_def() but for 16 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void
scale2x_16_def
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_16_def_whole
(
dst0
,
dst1
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_16_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_border
(
dst1
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 2 a row of pixels of 32 bits.
* This function operates like scale2x_8_def() but for 32 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void
scale2x_32_def
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_32_def_whole
(
dst0
,
dst1
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_32_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_border
(
dst1
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 2x3 a row of pixels of 8 bits.
* \note Like scale2x_8_def();
*/
void
scale2x3_8_def
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
scale2x_uint8
*
dst2
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_8_def_whole
(
dst0
,
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_8_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 2x3 a row of pixels of 16 bits.
* \note Like scale2x_16_def();
*/
void
scale2x3_16_def
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
scale2x_uint16
*
dst2
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_16_def_whole
(
dst0
,
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_16_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 2x3 a row of pixels of 32 bits.
* \note Like scale2x_32_def();
*/
void
scale2x3_32_def
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
scale2x_uint32
*
dst2
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_32_def_whole
(
dst0
,
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_32_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 2x4 a row of pixels of 8 bits.
* \note Like scale2x_8_def();
*/
void
scale2x4_8_def
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
scale2x_uint8
*
dst2
,
scale2x_uint8
*
dst3
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_8_def_whole
(
dst0
,
dst3
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_8_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_border
(
dst3
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 2x4 a row of pixels of 16 bits.
* \note Like scale2x_16_def();
*/
void
scale2x4_16_def
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
scale2x_uint16
*
dst2
,
scale2x_uint16
*
dst3
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_16_def_whole
(
dst0
,
dst3
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_16_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_border
(
dst3
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 2x4 a row of pixels of 32 bits.
* \note Like scale2x_32_def();
*/
void
scale2x4_32_def
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
scale2x_uint32
*
dst2
,
scale2x_uint32
*
dst3
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_32_def_whole
(
dst0
,
dst3
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
#else
scale2x_32_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_border
(
dst3
,
src2
,
src1
,
src0
,
count
);
#endif
}
/***************************************************************************/
/* Scale2x MMX implementation */
#if defined(__GNUC__) && defined(__i386__)
/*
* Apply the Scale2x effect at a single row.
* This function must be called only by the other scale2x functions.
*
* Considering the pixel map :
*
* ABC (src0)
* DEF (src1)
* GHI (src2)
*
* this functions compute 2 new pixels in substitution of the source pixel E
* like this map :
*
* ab (dst)
*
* with these variables :
*
* ¤t -> E
* ¤t_left -> D
* ¤t_right -> F
* ¤t_upper -> B
* ¤t_lower -> H
*
* %0 -> current_upper
* %1 -> current
* %2 -> current_lower
* %3 -> dst
* %4 -> counter
*
* %mm0 -> *current_left
* %mm1 -> *current_next
* %mm2 -> tmp0
* %mm3 -> tmp1
* %mm4 -> tmp2
* %mm5 -> tmp3
* %mm6 -> *current_upper
* %mm7 -> *current
*/
static
inline
void
scale2x_8_mmx_border
(
scale2x_uint8
*
dst
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
)
{
assert
(
count
>=
16
);
assert
(
count
%
8
==
0
);
/* always do the first and last run */
count
-=
2
*
8
;
__asm__
__volatile__
(
/* first run */
/* set the current, current_pre, current_next registers */
"movq 0(%1), %%mm0
\n
"
"movq 0(%1), %%mm7
\n
"
"movq 8(%1), %%mm1
\n
"
"psllq $56, %%mm0
\n
"
"psllq $56, %%mm1
\n
"
"psrlq $56, %%mm0
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $8, %%mm2
\n
"
"psrlq $8, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqb %%mm6, %%mm2
\n
"
"pcmpeqb %%mm6, %%mm4
\n
"
"pcmpeqb (%2), %%mm3
\n
"
"pcmpeqb (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqb %%mm1, %%mm2
\n
"
"pcmpeqb %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpcklbw %%mm4, %%mm2
\n
"
"punpckhbw %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
/* next */
"addl $8, %0
\n
"
"addl $8, %1
\n
"
"addl $8, %2
\n
"
"addl $16, %3
\n
"
/* central runs */
"shrl $3, %4
\n
"
"jz 1f
\n
"
"0:
\n
"
/* set the current, current_pre, current_next registers */
"movq -8(%1), %%mm0
\n
"
"movq (%1), %%mm7
\n
"
"movq 8(%1), %%mm1
\n
"
"psrlq $56, %%mm0
\n
"
"psllq $56, %%mm1
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $8, %%mm2
\n
"
"psrlq $8, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqb %%mm6, %%mm2
\n
"
"pcmpeqb %%mm6, %%mm4
\n
"
"pcmpeqb (%2), %%mm3
\n
"
"pcmpeqb (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqb %%mm1, %%mm2
\n
"
"pcmpeqb %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpcklbw %%mm4, %%mm2
\n
"
"punpckhbw %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
/* next */
"addl $8, %0
\n
"
"addl $8, %1
\n
"
"addl $8, %2
\n
"
"addl $16, %3
\n
"
"decl %4
\n
"
"jnz 0b
\n
"
"1:
\n
"
/* final run */
/* set the current, current_pre, current_next registers */
"movq (%1), %%mm1
\n
"
"movq (%1), %%mm7
\n
"
"movq -8(%1), %%mm0
\n
"
"psrlq $56, %%mm1
\n
"
"psrlq $56, %%mm0
\n
"
"psllq $56, %%mm1
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $8, %%mm2
\n
"
"psrlq $8, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqb %%mm6, %%mm2
\n
"
"pcmpeqb %%mm6, %%mm4
\n
"
"pcmpeqb (%2), %%mm3
\n
"
"pcmpeqb (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqb %%mm1, %%mm2
\n
"
"pcmpeqb %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpcklbw %%mm4, %%mm2
\n
"
"punpckhbw %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
:
"+r"
(
src0
),
"+r"
(
src1
),
"+r"
(
src2
),
"+r"
(
dst
),
"+r"
(
count
)
:
:
"cc"
);
}
static
inline
void
scale2x_16_mmx_border
(
scale2x_uint16
*
dst
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
)
{
assert
(
count
>=
8
);
assert
(
count
%
4
==
0
);
/* always do the first and last run */
count
-=
2
*
4
;
__asm__
__volatile__
(
/* first run */
/* set the current, current_pre, current_next registers */
"movq 0(%1), %%mm0
\n
"
"movq 0(%1), %%mm7
\n
"
"movq 8(%1), %%mm1
\n
"
"psllq $48, %%mm0
\n
"
"psllq $48, %%mm1
\n
"
"psrlq $48, %%mm0
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $16, %%mm2
\n
"
"psrlq $16, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqw %%mm6, %%mm2
\n
"
"pcmpeqw %%mm6, %%mm4
\n
"
"pcmpeqw (%2), %%mm3
\n
"
"pcmpeqw (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqw %%mm1, %%mm2
\n
"
"pcmpeqw %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpcklwd %%mm4, %%mm2
\n
"
"punpckhwd %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
/* next */
"addl $8, %0
\n
"
"addl $8, %1
\n
"
"addl $8, %2
\n
"
"addl $16, %3
\n
"
/* central runs */
"shrl $2, %4
\n
"
"jz 1f
\n
"
"0:
\n
"
/* set the current, current_pre, current_next registers */
"movq -8(%1), %%mm0
\n
"
"movq (%1), %%mm7
\n
"
"movq 8(%1), %%mm1
\n
"
"psrlq $48, %%mm0
\n
"
"psllq $48, %%mm1
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $16, %%mm2
\n
"
"psrlq $16, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqw %%mm6, %%mm2
\n
"
"pcmpeqw %%mm6, %%mm4
\n
"
"pcmpeqw (%2), %%mm3
\n
"
"pcmpeqw (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqw %%mm1, %%mm2
\n
"
"pcmpeqw %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpcklwd %%mm4, %%mm2
\n
"
"punpckhwd %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
/* next */
"addl $8, %0
\n
"
"addl $8, %1
\n
"
"addl $8, %2
\n
"
"addl $16, %3
\n
"
"decl %4
\n
"
"jnz 0b
\n
"
"1:
\n
"
/* final run */
/* set the current, current_pre, current_next registers */
"movq (%1), %%mm1
\n
"
"movq (%1), %%mm7
\n
"
"movq -8(%1), %%mm0
\n
"
"psrlq $48, %%mm1
\n
"
"psrlq $48, %%mm0
\n
"
"psllq $48, %%mm1
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $16, %%mm2
\n
"
"psrlq $16, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqw %%mm6, %%mm2
\n
"
"pcmpeqw %%mm6, %%mm4
\n
"
"pcmpeqw (%2), %%mm3
\n
"
"pcmpeqw (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqw %%mm1, %%mm2
\n
"
"pcmpeqw %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpcklwd %%mm4, %%mm2
\n
"
"punpckhwd %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
:
"+r"
(
src0
),
"+r"
(
src1
),
"+r"
(
src2
),
"+r"
(
dst
),
"+r"
(
count
)
:
:
"cc"
);
}
static
inline
void
scale2x_32_mmx_border
(
scale2x_uint32
*
dst
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
)
{
assert
(
count
>=
4
);
assert
(
count
%
2
==
0
);
/* always do the first and last run */
count
-=
2
*
2
;
__asm__
__volatile__
(
/* first run */
/* set the current, current_pre, current_next registers */
"movq 0(%1), %%mm0
\n
"
"movq 0(%1), %%mm7
\n
"
"movq 8(%1), %%mm1
\n
"
"psllq $32, %%mm0
\n
"
"psllq $32, %%mm1
\n
"
"psrlq $32, %%mm0
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $32, %%mm2
\n
"
"psrlq $32, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqd %%mm6, %%mm2
\n
"
"pcmpeqd %%mm6, %%mm4
\n
"
"pcmpeqd (%2), %%mm3
\n
"
"pcmpeqd (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqd %%mm1, %%mm2
\n
"
"pcmpeqd %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpckldq %%mm4, %%mm2
\n
"
"punpckhdq %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
/* next */
"addl $8, %0
\n
"
"addl $8, %1
\n
"
"addl $8, %2
\n
"
"addl $16, %3
\n
"
/* central runs */
"shrl $1, %4
\n
"
"jz 1f
\n
"
"0:
\n
"
/* set the current, current_pre, current_next registers */
"movq -8(%1), %%mm0
\n
"
"movq (%1), %%mm7
\n
"
"movq 8(%1), %%mm1
\n
"
"psrlq $32, %%mm0
\n
"
"psllq $32, %%mm1
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $32, %%mm2
\n
"
"psrlq $32, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqd %%mm6, %%mm2
\n
"
"pcmpeqd %%mm6, %%mm4
\n
"
"pcmpeqd (%2), %%mm3
\n
"
"pcmpeqd (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqd %%mm1, %%mm2
\n
"
"pcmpeqd %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpckldq %%mm4, %%mm2
\n
"
"punpckhdq %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
/* next */
"addl $8, %0
\n
"
"addl $8, %1
\n
"
"addl $8, %2
\n
"
"addl $16, %3
\n
"
"decl %4
\n
"
"jnz 0b
\n
"
"1:
\n
"
/* final run */
/* set the current, current_pre, current_next registers */
"movq (%1), %%mm1
\n
"
"movq (%1), %%mm7
\n
"
"movq -8(%1), %%mm0
\n
"
"psrlq $32, %%mm1
\n
"
"psrlq $32, %%mm0
\n
"
"psllq $32, %%mm1
\n
"
"movq %%mm7, %%mm2
\n
"
"movq %%mm7, %%mm3
\n
"
"psllq $32, %%mm2
\n
"
"psrlq $32, %%mm3
\n
"
"por %%mm2, %%mm0
\n
"
"por %%mm3, %%mm1
\n
"
/* current_upper */
"movq (%0), %%mm6
\n
"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"movq %%mm0, %%mm3
\n
"
"movq %%mm1, %%mm5
\n
"
"pcmpeqd %%mm6, %%mm2
\n
"
"pcmpeqd %%mm6, %%mm4
\n
"
"pcmpeqd (%2), %%mm3
\n
"
"pcmpeqd (%2), %%mm5
\n
"
"pandn %%mm2, %%mm3
\n
"
"pandn %%mm4, %%mm5
\n
"
"movq %%mm0, %%mm2
\n
"
"movq %%mm1, %%mm4
\n
"
"pcmpeqd %%mm1, %%mm2
\n
"
"pcmpeqd %%mm0, %%mm4
\n
"
"pandn %%mm3, %%mm2
\n
"
"pandn %%mm5, %%mm4
\n
"
"movq %%mm2, %%mm3
\n
"
"movq %%mm4, %%mm5
\n
"
"pand %%mm6, %%mm2
\n
"
"pand %%mm6, %%mm4
\n
"
"pandn %%mm7, %%mm3
\n
"
"pandn %%mm7, %%mm5
\n
"
"por %%mm3, %%mm2
\n
"
"por %%mm5, %%mm4
\n
"
/* set *dst */
"movq %%mm2, %%mm3
\n
"
"punpckldq %%mm4, %%mm2
\n
"
"punpckhdq %%mm4, %%mm3
\n
"
"movq %%mm2, (%3)
\n
"
"movq %%mm3, 8(%3)
\n
"
:
"+r"
(
src0
),
"+r"
(
src1
),
"+r"
(
src2
),
"+r"
(
dst
),
"+r"
(
count
)
:
:
"cc"
);
}
/**
* Scale by a factor of 2 a row of pixels of 8 bits.
* This is a very fast MMX implementation.
* The implementation uses a combination of cmp/and/not operations to
* completly remove the need of conditional jumps. This trick give the
* major speed improvement.
* Also, using the 8 bytes MMX registers more than one pixel are computed
* at the same time.
* Before calling this function you must ensure that the currenct CPU supports
* the MMX instruction set. After calling it you must be sure to call the EMMS
* instruction before any floating-point operation.
* The pixels over the left and right borders are assumed of the same color of
* the pixels on the border.
* Note that the implementation is optimized to write data sequentially to
* maximize the bandwidth on video memory.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows. It must
* be at least 16 and a multiple of 8.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void
scale2x_8_mmx
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
)
{
if
(
count
%
8
!=
0
||
count
<
16
)
{
scale2x_8_def
(
dst0
,
dst1
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_8_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_8_mmx_border
(
dst1
,
src2
,
src1
,
src0
,
count
);
}
}
/**
* Scale by a factor of 2 a row of pixels of 16 bits.
* This function operates like scale2x_8_mmx() but for 16 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows. It must
* be at least 8 and a multiple of 4.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void
scale2x_16_mmx
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
)
{
if
(
count
%
4
!=
0
||
count
<
8
)
{
scale2x_16_def
(
dst0
,
dst1
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_16_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_16_mmx_border
(
dst1
,
src2
,
src1
,
src0
,
count
);
}
}
/**
* Scale by a factor of 2 a row of pixels of 32 bits.
* This function operates like scale2x_8_mmx() but for 32 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows. It must
* be at least 4 and a multiple of 2.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void
scale2x_32_mmx
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
)
{
if
(
count
%
2
!=
0
||
count
<
4
)
{
scale2x_32_def
(
dst0
,
dst1
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_32_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_32_mmx_border
(
dst1
,
src2
,
src1
,
src0
,
count
);
}
}
/**
* Scale by a factor of 2x3 a row of pixels of 8 bits.
* This function operates like scale2x_8_mmx() but with an expansion
* factor of 2x3 instead of 2x2.
*/
void
scale2x3_8_mmx
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
scale2x_uint8
*
dst2
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
)
{
if
(
count
%
8
!=
0
||
count
<
16
)
{
scale2x3_8_def
(
dst0
,
dst1
,
dst2
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_8_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_8_mmx_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
}
}
/**
* Scale by a factor of 2x3 a row of pixels of 16 bits.
* This function operates like scale2x_16_mmx() but with an expansion
* factor of 2x3 instead of 2x2.
*/
void
scale2x3_16_mmx
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
scale2x_uint16
*
dst2
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
)
{
if
(
count
%
4
!=
0
||
count
<
8
)
{
scale2x3_16_def
(
dst0
,
dst1
,
dst2
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_16_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_16_mmx_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
}
}
/**
* Scale by a factor of 2x3 a row of pixels of 32 bits.
* This function operates like scale2x_32_mmx() but with an expansion
* factor of 2x3 instead of 2x2.
*/
void
scale2x3_32_mmx
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
scale2x_uint32
*
dst2
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
)
{
if
(
count
%
2
!=
0
||
count
<
4
)
{
scale2x3_32_def
(
dst0
,
dst1
,
dst2
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_32_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_32_mmx_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
}
}
/**
* Scale by a factor of 2x4 a row of pixels of 8 bits.
* This function operates like scale2x_8_mmx() but with an expansion
* factor of 2x4 instead of 2x2.
*/
void
scale2x4_8_mmx
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
scale2x_uint8
*
dst2
,
scale2x_uint8
*
dst3
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
)
{
if
(
count
%
8
!=
0
||
count
<
16
)
{
scale2x4_8_def
(
dst0
,
dst1
,
dst2
,
dst3
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_8_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_8_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_8_mmx_border
(
dst3
,
src2
,
src1
,
src0
,
count
);
}
}
/**
* Scale by a factor of 2x4 a row of pixels of 16 bits.
* This function operates like scale2x_16_mmx() but with an expansion
* factor of 2x4 instead of 2x2.
*/
void
scale2x4_16_mmx
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
scale2x_uint16
*
dst2
,
scale2x_uint16
*
dst3
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
)
{
if
(
count
%
4
!=
0
||
count
<
8
)
{
scale2x4_16_def
(
dst0
,
dst1
,
dst2
,
dst3
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_16_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_16_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_16_mmx_border
(
dst3
,
src2
,
src1
,
src0
,
count
);
}
}
/**
* Scale by a factor of 2x4 a row of pixels of 32 bits.
* This function operates like scale2x_32_mmx() but with an expansion
* factor of 2x4 instead of 2x2.
*/
void
scale2x4_32_mmx
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
scale2x_uint32
*
dst2
,
scale2x_uint32
*
dst3
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
)
{
if
(
count
%
2
!=
0
||
count
<
4
)
{
scale2x4_32_def
(
dst0
,
dst1
,
dst2
,
dst3
,
src0
,
src1
,
src2
,
count
);
}
else
{
scale2x_32_mmx_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale2x_32_def_center
(
dst2
,
src0
,
src1
,
src2
,
count
);
scale2x_32_mmx_border
(
dst3
,
src2
,
src1
,
src0
,
count
);
}
}
#endif
src/scale2x/scale2x.h
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __SCALE2X_H
#define __SCALE2X_H
#define restrict
typedef
unsigned
char
scale2x_uint8
;
typedef
unsigned
short
scale2x_uint16
;
typedef
unsigned
scale2x_uint32
;
void
scale2x_8_def
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
);
void
scale2x_16_def
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
);
void
scale2x_32_def
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
);
void
scale2x3_8_def
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
scale2x_uint8
*
dst2
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
);
void
scale2x3_16_def
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
scale2x_uint16
*
dst2
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
);
void
scale2x3_32_def
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
scale2x_uint32
*
dst2
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
);
void
scale2x4_8_def
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
scale2x_uint8
*
dst2
,
scale2x_uint8
*
dst3
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
);
void
scale2x4_16_def
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
scale2x_uint16
*
dst2
,
scale2x_uint16
*
dst3
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
);
void
scale2x4_32_def
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
scale2x_uint32
*
dst2
,
scale2x_uint32
*
dst3
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
);
#if defined(__GNUC__) && defined(__i386__)
void
scale2x_8_mmx
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
);
void
scale2x_16_mmx
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
);
void
scale2x_32_mmx
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
);
void
scale2x3_8_mmx
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
scale2x_uint8
*
dst2
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
);
void
scale2x3_16_mmx
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
scale2x_uint16
*
dst2
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
);
void
scale2x3_32_mmx
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
scale2x_uint32
*
dst2
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
);
void
scale2x4_8_mmx
(
scale2x_uint8
*
dst0
,
scale2x_uint8
*
dst1
,
scale2x_uint8
*
dst2
,
scale2x_uint8
*
dst3
,
const
scale2x_uint8
*
src0
,
const
scale2x_uint8
*
src1
,
const
scale2x_uint8
*
src2
,
unsigned
count
);
void
scale2x4_16_mmx
(
scale2x_uint16
*
dst0
,
scale2x_uint16
*
dst1
,
scale2x_uint16
*
dst2
,
scale2x_uint16
*
dst3
,
const
scale2x_uint16
*
src0
,
const
scale2x_uint16
*
src1
,
const
scale2x_uint16
*
src2
,
unsigned
count
);
void
scale2x4_32_mmx
(
scale2x_uint32
*
dst0
,
scale2x_uint32
*
dst1
,
scale2x_uint32
*
dst2
,
scale2x_uint32
*
dst3
,
const
scale2x_uint32
*
src0
,
const
scale2x_uint32
*
src1
,
const
scale2x_uint32
*
src2
,
unsigned
count
);
/**
* End the use of the MMX instructions.
* This function must be called before using any floating-point operations.
*/
static
inline
void
scale2x_mmx_emms
(
void
)
{
__asm__
__volatile__
(
"emms"
);
}
#endif
#endif
src/scale2x/scale3x.cpp
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file contains a C and MMX implementation of the Scale2x effect.
*
* You can find an high level description of the effect at :
*
* http://scale2x.sourceforge.net/
*
* Alternatively at the previous license terms, you are allowed to use this
* code in your program with these conditions:
* - the program is not used in commercial activities.
* - the whole source code of the program is released with the binary.
* - derivative works of the program are allowed.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "scale3x.h"
#include <assert.h>
/***************************************************************************/
/* Scale3x C implementation */
/**
* Define the macro USE_SCALE_RANDOMWRITE to enable
* an optimized version which writes memory in random order.
* This version is a little faster if you write in system memory.
* But it's a lot slower if you write in video memory.
* So, enable it only if you are sure to never write directly in video memory.
*/
/* #define USE_SCALE_RANDOMWRITE */
static
inline
void
scale3x_8_def_whole
(
scale3x_uint8
*
restrict
dst0
,
scale3x_uint8
*
restrict
dst1
,
scale3x_uint8
*
restrict
dst2
,
const
scale3x_uint8
*
restrict
src0
,
const
scale3x_uint8
*
restrict
src1
,
const
scale3x_uint8
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
dst1
[
0
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
1
]
==
src2
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
3
;
dst1
+=
3
;
dst2
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst0
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
dst1
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst2
[
1
]
=
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
1
]
==
src2
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
3
;
dst1
+=
3
;
dst2
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst0
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
||
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst2
[
1
]
=
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
}
static
inline
void
scale3x_8_def_border
(
scale3x_uint8
*
restrict
dst
,
const
scale3x_uint8
*
restrict
src0
,
const
scale3x_uint8
*
restrict
src1
,
const
scale3x_uint8
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
||
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
}
static
inline
void
scale3x_8_def_center
(
scale3x_uint8
*
restrict
dst
,
const
scale3x_uint8
*
restrict
src0
,
const
scale3x_uint8
*
restrict
src1
,
const
scale3x_uint8
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
}
static
inline
void
scale3x_16_def_whole
(
scale3x_uint16
*
restrict
dst0
,
scale3x_uint16
*
restrict
dst1
,
scale3x_uint16
*
restrict
dst2
,
const
scale3x_uint16
*
restrict
src0
,
const
scale3x_uint16
*
restrict
src1
,
const
scale3x_uint16
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
dst1
[
0
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
1
]
==
src2
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
3
;
dst1
+=
3
;
dst2
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst0
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
dst1
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst2
[
1
]
=
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
1
]
==
src2
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
3
;
dst1
+=
3
;
dst2
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst0
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
||
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst2
[
1
]
=
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
}
static
inline
void
scale3x_16_def_border
(
scale3x_uint16
*
restrict
dst
,
const
scale3x_uint16
*
restrict
src0
,
const
scale3x_uint16
*
restrict
src1
,
const
scale3x_uint16
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
||
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
}
static
inline
void
scale3x_16_def_center
(
scale3x_uint16
*
restrict
dst
,
const
scale3x_uint16
*
restrict
src0
,
const
scale3x_uint16
*
restrict
src1
,
const
scale3x_uint16
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
}
static
inline
void
scale3x_32_def_whole
(
scale3x_uint32
*
restrict
dst0
,
scale3x_uint32
*
restrict
dst1
,
scale3x_uint32
*
restrict
dst2
,
const
scale3x_uint32
*
restrict
src0
,
const
scale3x_uint32
*
restrict
src1
,
const
scale3x_uint32
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
dst1
[
0
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
1
]
==
src2
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
3
;
dst1
+=
3
;
dst2
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst0
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
dst1
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst2
[
1
]
=
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
1
]
==
src2
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst0
+=
3
;
dst1
+=
3
;
dst2
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst0
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst0
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
||
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst2
[
0
]
=
src1
[
-
1
]
==
src2
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst2
[
1
]
=
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
?
src2
[
0
]
:
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
else
{
dst0
[
0
]
=
src1
[
0
];
dst0
[
1
]
=
src1
[
0
];
dst0
[
2
]
=
src1
[
0
];
dst1
[
0
]
=
src1
[
0
];
dst1
[
1
]
=
src1
[
0
];
dst1
[
2
]
=
src1
[
0
];
dst2
[
0
]
=
src1
[
0
];
dst2
[
1
]
=
src1
[
0
];
dst2
[
2
]
=
src1
[
0
];
}
}
static
inline
void
scale3x_32_def_border
(
scale3x_uint32
*
restrict
dst
,
const
scale3x_uint32
*
restrict
src0
,
const
scale3x_uint32
*
restrict
src1
,
const
scale3x_uint32
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
||
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
1
]
==
src0
[
0
]
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
src1
[
-
1
]
==
src0
[
0
]
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
||
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src0
[
0
]
:
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
}
static
inline
void
scale3x_32_def_center
(
scale3x_uint32
*
restrict
dst
,
const
scale3x_uint32
*
restrict
src0
,
const
scale3x_uint32
*
restrict
src1
,
const
scale3x_uint32
*
restrict
src2
,
unsigned
count
)
{
assert
(
count
>=
2
);
/* first pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
0
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
/* central pixels */
count
-=
2
;
while
(
count
)
{
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
1
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
1
])
||
(
src1
[
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
1
])
?
src1
[
1
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
++
src0
;
++
src1
;
++
src2
;
dst
+=
3
;
--
count
;
}
/* last pixel */
if
(
src0
[
0
]
!=
src2
[
0
]
&&
src1
[
-
1
]
!=
src1
[
0
])
{
dst
[
0
]
=
(
src1
[
-
1
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
-
1
])
||
(
src1
[
-
1
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
-
1
])
?
src1
[
-
1
]
:
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
(
src1
[
0
]
==
src0
[
0
]
&&
src1
[
0
]
!=
src2
[
0
])
||
(
src1
[
0
]
==
src2
[
0
]
&&
src1
[
0
]
!=
src0
[
0
])
?
src1
[
0
]
:
src1
[
0
];
}
else
{
dst
[
0
]
=
src1
[
0
];
dst
[
1
]
=
src1
[
0
];
dst
[
2
]
=
src1
[
0
];
}
}
/**
* Scale by a factor of 3 a row of pixels of 8 bits.
* The function is implemented in C.
* The pixels over the left and right borders are assumed of the same color of
* the pixels on the border.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, triple length in pixels.
* \param dst1 Second destination row, triple length in pixels.
* \param dst2 Third destination row, triple length in pixels.
*/
void
scale3x_8_def
(
scale3x_uint8
*
dst0
,
scale3x_uint8
*
dst1
,
scale3x_uint8
*
dst2
,
const
scale3x_uint8
*
src0
,
const
scale3x_uint8
*
src1
,
const
scale3x_uint8
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale3x_8_def_whole
(
dst0
,
dst1
,
dst2
,
src0
,
src1
,
src2
,
count
);
#else
scale3x_8_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale3x_8_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale3x_8_def_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 3 a row of pixels of 16 bits.
* This function operates like scale3x_8_def() but for 16 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, triple length in pixels.
* \param dst1 Second destination row, triple length in pixels.
* \param dst2 Third destination row, triple length in pixels.
*/
void
scale3x_16_def
(
scale3x_uint16
*
dst0
,
scale3x_uint16
*
dst1
,
scale3x_uint16
*
dst2
,
const
scale3x_uint16
*
src0
,
const
scale3x_uint16
*
src1
,
const
scale3x_uint16
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale3x_16_def_whole
(
dst0
,
dst1
,
dst2
,
src0
,
src1
,
src2
,
count
);
#else
scale3x_16_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale3x_16_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale3x_16_def_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
#endif
}
/**
* Scale by a factor of 3 a row of pixels of 32 bits.
* This function operates like scale3x_8_def() but for 32 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, triple length in pixels.
* \param dst1 Second destination row, triple length in pixels.
* \param dst2 Third destination row, triple length in pixels.
*/
void
scale3x_32_def
(
scale3x_uint32
*
dst0
,
scale3x_uint32
*
dst1
,
scale3x_uint32
*
dst2
,
const
scale3x_uint32
*
src0
,
const
scale3x_uint32
*
src1
,
const
scale3x_uint32
*
src2
,
unsigned
count
)
{
#ifdef USE_SCALE_RANDOMWRITE
scale3x_32_def_whole
(
dst0
,
dst1
,
dst2
,
src0
,
src1
,
src2
,
count
);
#else
scale3x_32_def_border
(
dst0
,
src0
,
src1
,
src2
,
count
);
scale3x_32_def_center
(
dst1
,
src0
,
src1
,
src2
,
count
);
scale3x_32_def_border
(
dst2
,
src2
,
src1
,
src0
,
count
);
#endif
}
src/scale2x/scale3x.h
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __SCALE3X_H
#define __SCALE3X_H
#define restrict
typedef
unsigned
char
scale3x_uint8
;
typedef
unsigned
short
scale3x_uint16
;
typedef
unsigned
scale3x_uint32
;
void
scale3x_8_def
(
scale3x_uint8
*
dst0
,
scale3x_uint8
*
dst1
,
scale3x_uint8
*
dst2
,
const
scale3x_uint8
*
src0
,
const
scale3x_uint8
*
src1
,
const
scale3x_uint8
*
src2
,
unsigned
count
);
void
scale3x_16_def
(
scale3x_uint16
*
dst0
,
scale3x_uint16
*
dst1
,
scale3x_uint16
*
dst2
,
const
scale3x_uint16
*
src0
,
const
scale3x_uint16
*
src1
,
const
scale3x_uint16
*
src2
,
unsigned
count
);
void
scale3x_32_def
(
scale3x_uint32
*
dst0
,
scale3x_uint32
*
dst1
,
scale3x_uint32
*
dst2
,
const
scale3x_uint32
*
src0
,
const
scale3x_uint32
*
src1
,
const
scale3x_uint32
*
src2
,
unsigned
count
);
#endif
src/scale2x/scalebit.cpp
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2003, 2004 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file contains an example implementation of the Scale effect
* applyed to a generic bitmap.
*
* You can find an high level description of the effect at :
*
* http://scale2x.sourceforge.net/
*
* Alternatively at the previous license terms, you are allowed to use this
* code in your program with these conditions:
* - the program is not used in commercial activities.
* - the whole source code of the program is released with the binary.
* - derivative works of the program are allowed.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "scale2x.h"
#include "scale3x.h"
#if HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include <assert.h>
#include <stdlib.h>
#define SSDST(bits, num) (scale2x_uint##bits *)dst##num
#define SSSRC(bits, num) (const scale2x_uint##bits *)src##num
/**
* Apply the Scale2x effect on a group of rows. Used internally.
*/
static
inline
void
stage_scale2x
(
void
*
dst0
,
void
*
dst1
,
const
void
*
src0
,
const
void
*
src1
,
const
void
*
src2
,
unsigned
pixel
,
unsigned
pixel_per_row
)
{
switch
(
pixel
)
{
#if defined(__GNUC__) && defined(__i386__)
case
1
:
scale2x_8_mmx
(
SSDST
(
8
,
0
),
SSDST
(
8
,
1
),
SSSRC
(
8
,
0
),
SSSRC
(
8
,
1
),
SSSRC
(
8
,
2
),
pixel_per_row
);
break
;
case
2
:
scale2x_16_mmx
(
SSDST
(
16
,
0
),
SSDST
(
16
,
1
),
SSSRC
(
16
,
0
),
SSSRC
(
16
,
1
),
SSSRC
(
16
,
2
),
pixel_per_row
);
break
;
case
4
:
scale2x_32_mmx
(
SSDST
(
32
,
0
),
SSDST
(
32
,
1
),
SSSRC
(
32
,
0
),
SSSRC
(
32
,
1
),
SSSRC
(
32
,
2
),
pixel_per_row
);
break
;
#else
case
1
:
scale2x_8_def
(
SSDST
(
8
,
0
),
SSDST
(
8
,
1
),
SSSRC
(
8
,
0
),
SSSRC
(
8
,
1
),
SSSRC
(
8
,
2
),
pixel_per_row
);
break
;
case
2
:
scale2x_16_def
(
SSDST
(
16
,
0
),
SSDST
(
16
,
1
),
SSSRC
(
16
,
0
),
SSSRC
(
16
,
1
),
SSSRC
(
16
,
2
),
pixel_per_row
);
break
;
case
4
:
scale2x_32_def
(
SSDST
(
32
,
0
),
SSDST
(
32
,
1
),
SSSRC
(
32
,
0
),
SSSRC
(
32
,
1
),
SSSRC
(
32
,
2
),
pixel_per_row
);
break
;
#endif
}
}
/**
* Apply the Scale2x3 effect on a group of rows. Used internally.
*/
static
inline
void
stage_scale2x3
(
void
*
dst0
,
void
*
dst1
,
void
*
dst2
,
const
void
*
src0
,
const
void
*
src1
,
const
void
*
src2
,
unsigned
pixel
,
unsigned
pixel_per_row
)
{
switch
(
pixel
)
{
#if defined(__GNUC__) && defined(__i386__)
case
1
:
scale2x3_8_mmx
(
SSDST
(
8
,
0
),
SSDST
(
8
,
1
),
SSDST
(
8
,
2
),
SSSRC
(
8
,
0
),
SSSRC
(
8
,
1
),
SSSRC
(
8
,
2
),
pixel_per_row
);
break
;
case
2
:
scale2x3_16_mmx
(
SSDST
(
16
,
0
),
SSDST
(
16
,
1
),
SSDST
(
16
,
2
),
SSSRC
(
16
,
0
),
SSSRC
(
16
,
1
),
SSSRC
(
16
,
2
),
pixel_per_row
);
break
;
case
4
:
scale2x3_32_mmx
(
SSDST
(
32
,
0
),
SSDST
(
32
,
1
),
SSDST
(
32
,
2
),
SSSRC
(
32
,
0
),
SSSRC
(
32
,
1
),
SSSRC
(
32
,
2
),
pixel_per_row
);
break
;
#else
case
1
:
scale2x3_8_def
(
SSDST
(
8
,
0
),
SSDST
(
8
,
1
),
SSDST
(
8
,
2
),
SSSRC
(
8
,
0
),
SSSRC
(
8
,
1
),
SSSRC
(
8
,
2
),
pixel_per_row
);
break
;
case
2
:
scale2x3_16_def
(
SSDST
(
16
,
0
),
SSDST
(
16
,
1
),
SSDST
(
16
,
2
),
SSSRC
(
16
,
0
),
SSSRC
(
16
,
1
),
SSSRC
(
16
,
2
),
pixel_per_row
);
break
;
case
4
:
scale2x3_32_def
(
SSDST
(
32
,
0
),
SSDST
(
32
,
1
),
SSDST
(
32
,
2
),
SSSRC
(
32
,
0
),
SSSRC
(
32
,
1
),
SSSRC
(
32
,
2
),
pixel_per_row
);
break
;
#endif
}
}
/**
* Apply the Scale2x4 effect on a group of rows. Used internally.
*/
static
inline
void
stage_scale2x4
(
void
*
dst0
,
void
*
dst1
,
void
*
dst2
,
void
*
dst3
,
const
void
*
src0
,
const
void
*
src1
,
const
void
*
src2
,
unsigned
pixel
,
unsigned
pixel_per_row
)
{
switch
(
pixel
)
{
#if defined(__GNUC__) && defined(__i386__)
case
1
:
scale2x4_8_mmx
(
SSDST
(
8
,
0
),
SSDST
(
8
,
1
),
SSDST
(
8
,
2
),
SSDST
(
8
,
3
),
SSSRC
(
8
,
0
),
SSSRC
(
8
,
1
),
SSSRC
(
8
,
2
),
pixel_per_row
);
break
;
case
2
:
scale2x4_16_mmx
(
SSDST
(
16
,
0
),
SSDST
(
16
,
1
),
SSDST
(
16
,
2
),
SSDST
(
16
,
3
),
SSSRC
(
16
,
0
),
SSSRC
(
16
,
1
),
SSSRC
(
16
,
2
),
pixel_per_row
);
break
;
case
4
:
scale2x4_32_mmx
(
SSDST
(
32
,
0
),
SSDST
(
32
,
1
),
SSDST
(
32
,
2
),
SSDST
(
32
,
3
),
SSSRC
(
32
,
0
),
SSSRC
(
32
,
1
),
SSSRC
(
32
,
2
),
pixel_per_row
);
break
;
#else
case
1
:
scale2x4_8_def
(
SSDST
(
8
,
0
),
SSDST
(
8
,
1
),
SSDST
(
8
,
2
),
SSDST
(
8
,
3
),
SSSRC
(
8
,
0
),
SSSRC
(
8
,
1
),
SSSRC
(
8
,
2
),
pixel_per_row
);
break
;
case
2
:
scale2x4_16_def
(
SSDST
(
16
,
0
),
SSDST
(
16
,
1
),
SSDST
(
16
,
2
),
SSDST
(
16
,
3
),
SSSRC
(
16
,
0
),
SSSRC
(
16
,
1
),
SSSRC
(
16
,
2
),
pixel_per_row
);
break
;
case
4
:
scale2x4_32_def
(
SSDST
(
32
,
0
),
SSDST
(
32
,
1
),
SSDST
(
32
,
2
),
SSDST
(
32
,
3
),
SSSRC
(
32
,
0
),
SSSRC
(
32
,
1
),
SSSRC
(
32
,
2
),
pixel_per_row
);
break
;
#endif
}
}
/**
* Apply the Scale3x effect on a group of rows. Used internally.
*/
static
inline
void
stage_scale3x
(
void
*
dst0
,
void
*
dst1
,
void
*
dst2
,
const
void
*
src0
,
const
void
*
src1
,
const
void
*
src2
,
unsigned
pixel
,
unsigned
pixel_per_row
)
{
switch
(
pixel
)
{
case
1
:
scale3x_8_def
(
SSDST
(
8
,
0
),
SSDST
(
8
,
1
),
SSDST
(
8
,
2
),
SSSRC
(
8
,
0
),
SSSRC
(
8
,
1
),
SSSRC
(
8
,
2
),
pixel_per_row
);
break
;
case
2
:
scale3x_16_def
(
SSDST
(
16
,
0
),
SSDST
(
16
,
1
),
SSDST
(
16
,
2
),
SSSRC
(
16
,
0
),
SSSRC
(
16
,
1
),
SSSRC
(
16
,
2
),
pixel_per_row
);
break
;
case
4
:
scale3x_32_def
(
SSDST
(
32
,
0
),
SSDST
(
32
,
1
),
SSDST
(
32
,
2
),
SSSRC
(
32
,
0
),
SSSRC
(
32
,
1
),
SSSRC
(
32
,
2
),
pixel_per_row
);
break
;
}
}
/**
* Apply the Scale4x effect on a group of rows. Used internally.
*/
static
inline
void
stage_scale4x
(
void
*
dst0
,
void
*
dst1
,
void
*
dst2
,
void
*
dst3
,
const
void
*
src0
,
const
void
*
src1
,
const
void
*
src2
,
const
void
*
src3
,
unsigned
pixel
,
unsigned
pixel_per_row
)
{
stage_scale2x
(
dst0
,
dst1
,
src0
,
src1
,
src2
,
pixel
,
2
*
pixel_per_row
);
stage_scale2x
(
dst2
,
dst3
,
src1
,
src2
,
src3
,
pixel
,
2
*
pixel_per_row
);
}
#define SCDST(i) (dst+(i)*dst_slice)
#define SCSRC(i) (src+(i)*src_slice)
#define SCMID(i) (mid[(i)])
/**
* Apply the Scale2x effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 2x2 times the size of the source bitmap.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static
void
scale2x
(
void
*
void_dst
,
unsigned
dst_slice
,
const
void
*
void_src
,
unsigned
src_slice
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
)
{
unsigned
char
*
dst
=
(
unsigned
char
*
)
void_dst
;
const
unsigned
char
*
src
=
(
const
unsigned
char
*
)
void_src
;
unsigned
count
;
assert
(
height
>=
2
);
count
=
height
;
stage_scale2x
(
SCDST
(
0
),
SCDST
(
1
),
SCSRC
(
0
),
SCSRC
(
0
),
SCSRC
(
1
),
pixel
,
width
);
dst
=
SCDST
(
2
);
count
-=
2
;
while
(
count
)
{
stage_scale2x
(
SCDST
(
0
),
SCDST
(
1
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
2
),
pixel
,
width
);
dst
=
SCDST
(
2
);
src
=
SCSRC
(
1
);
--
count
;
}
stage_scale2x
(
SCDST
(
0
),
SCDST
(
1
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
1
),
pixel
,
width
);
#if defined(__GNUC__) && defined(__i386__)
scale2x_mmx_emms
();
#endif
}
/**
* Apply the Scale2x3 effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 2x3 times the size of the source bitmap.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static
void
scale2x3
(
void
*
void_dst
,
unsigned
dst_slice
,
const
void
*
void_src
,
unsigned
src_slice
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
)
{
unsigned
char
*
dst
=
(
unsigned
char
*
)
void_dst
;
const
unsigned
char
*
src
=
(
const
unsigned
char
*
)
void_src
;
unsigned
count
;
assert
(
height
>=
2
);
count
=
height
;
stage_scale2x3
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCSRC
(
0
),
SCSRC
(
0
),
SCSRC
(
1
),
pixel
,
width
);
dst
=
SCDST
(
3
);
count
-=
2
;
while
(
count
)
{
stage_scale2x3
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
2
),
pixel
,
width
);
dst
=
SCDST
(
3
);
src
=
SCSRC
(
1
);
--
count
;
}
stage_scale2x3
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
1
),
pixel
,
width
);
#if defined(__GNUC__) && defined(__i386__)
scale2x_mmx_emms
();
#endif
}
/**
* Apply the Scale2x4 effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 2x4 times the size of the source bitmap.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static
void
scale2x4
(
void
*
void_dst
,
unsigned
dst_slice
,
const
void
*
void_src
,
unsigned
src_slice
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
)
{
unsigned
char
*
dst
=
(
unsigned
char
*
)
void_dst
;
const
unsigned
char
*
src
=
(
const
unsigned
char
*
)
void_src
;
unsigned
count
;
assert
(
height
>=
2
);
count
=
height
;
stage_scale2x4
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCDST
(
3
),
SCSRC
(
0
),
SCSRC
(
0
),
SCSRC
(
1
),
pixel
,
width
);
dst
=
SCDST
(
4
);
count
-=
2
;
while
(
count
)
{
stage_scale2x4
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCDST
(
3
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
2
),
pixel
,
width
);
dst
=
SCDST
(
4
);
src
=
SCSRC
(
1
);
--
count
;
}
stage_scale2x4
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCDST
(
3
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
1
),
pixel
,
width
);
#if defined(__GNUC__) && defined(__i386__)
scale2x_mmx_emms
();
#endif
}
/**
* Apply the Scale3x effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 3x3 times the size of the source bitmap.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static
void
scale3x
(
void
*
void_dst
,
unsigned
dst_slice
,
const
void
*
void_src
,
unsigned
src_slice
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
)
{
unsigned
char
*
dst
=
(
unsigned
char
*
)
void_dst
;
const
unsigned
char
*
src
=
(
const
unsigned
char
*
)
void_src
;
unsigned
count
;
assert
(
height
>=
2
);
count
=
height
;
stage_scale3x
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCSRC
(
0
),
SCSRC
(
0
),
SCSRC
(
1
),
pixel
,
width
);
dst
=
SCDST
(
3
);
count
-=
2
;
while
(
count
)
{
stage_scale3x
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
2
),
pixel
,
width
);
dst
=
SCDST
(
3
);
src
=
SCSRC
(
1
);
--
count
;
}
stage_scale3x
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
1
),
pixel
,
width
);
}
/**
* Apply the Scale4x effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
* \note This function requires also a small buffer bitmap used internally to store
* intermediate results. This bitmap must have at least an horizontal size in bytes of 2*width*pixel,
* and a vertical size of 6 rows. The memory of this buffer must not be allocated
* in video memory because it's also read and not only written. Generally
* a heap (malloc) or a stack (alloca) buffer is the best choice.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_mid Pointer at the first pixel of the buffer bitmap.
* \param mid_slice Size in bytes of a buffer bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static
void
scale4x_buf
(
void
*
void_dst
,
unsigned
dst_slice
,
void
*
void_mid
,
unsigned
mid_slice
,
const
void
*
void_src
,
unsigned
src_slice
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
)
{
unsigned
char
*
dst
=
(
unsigned
char
*
)
void_dst
;
const
unsigned
char
*
src
=
(
const
unsigned
char
*
)
void_src
;
unsigned
count
;
unsigned
char
*
mid
[
6
];
assert
(
height
>=
4
);
count
=
height
;
/* set the 6 buffer pointers */
mid
[
0
]
=
(
unsigned
char
*
)
void_mid
;
mid
[
1
]
=
mid
[
0
]
+
mid_slice
;
mid
[
2
]
=
mid
[
1
]
+
mid_slice
;
mid
[
3
]
=
mid
[
2
]
+
mid_slice
;
mid
[
4
]
=
mid
[
3
]
+
mid_slice
;
mid
[
5
]
=
mid
[
4
]
+
mid_slice
;
stage_scale2x
(
SCMID
(
-
2
+
6
),
SCMID
(
-
1
+
6
),
SCSRC
(
0
),
SCSRC
(
0
),
SCSRC
(
1
),
pixel
,
width
);
stage_scale2x
(
SCMID
(
0
),
SCMID
(
1
),
SCSRC
(
0
),
SCSRC
(
1
),
SCSRC
(
2
),
pixel
,
width
);
stage_scale2x
(
SCMID
(
2
),
SCMID
(
3
),
SCSRC
(
1
),
SCSRC
(
2
),
SCSRC
(
3
),
pixel
,
width
);
stage_scale4x
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCDST
(
3
),
SCMID
(
-
2
+
6
),
SCMID
(
-
2
+
6
),
SCMID
(
-
1
+
6
),
SCMID
(
0
),
pixel
,
width
);
dst
=
SCDST
(
4
);
stage_scale4x
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCDST
(
3
),
SCMID
(
-
1
+
6
),
SCMID
(
0
),
SCMID
(
1
),
SCMID
(
2
),
pixel
,
width
);
dst
=
SCDST
(
4
);
count
-=
4
;
while
(
count
)
{
unsigned
char
*
tmp
;
stage_scale2x
(
SCMID
(
4
),
SCMID
(
5
),
SCSRC
(
2
),
SCSRC
(
3
),
SCSRC
(
4
),
pixel
,
width
);
stage_scale4x
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCDST
(
3
),
SCMID
(
1
),
SCMID
(
2
),
SCMID
(
3
),
SCMID
(
4
),
pixel
,
width
);
dst
=
SCDST
(
4
);
src
=
SCSRC
(
1
);
tmp
=
SCMID
(
0
);
/* shift by 2 position */
SCMID
(
0
)
=
SCMID
(
2
);
SCMID
(
2
)
=
SCMID
(
4
);
SCMID
(
4
)
=
tmp
;
tmp
=
SCMID
(
1
);
SCMID
(
1
)
=
SCMID
(
3
);
SCMID
(
3
)
=
SCMID
(
5
);
SCMID
(
5
)
=
tmp
;
--
count
;
}
stage_scale2x
(
SCMID
(
4
),
SCMID
(
5
),
SCSRC
(
2
),
SCSRC
(
3
),
SCSRC
(
3
),
pixel
,
width
);
stage_scale4x
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCDST
(
3
),
SCMID
(
1
),
SCMID
(
2
),
SCMID
(
3
),
SCMID
(
4
),
pixel
,
width
);
dst
=
SCDST
(
4
);
stage_scale4x
(
SCDST
(
0
),
SCDST
(
1
),
SCDST
(
2
),
SCDST
(
3
),
SCMID
(
3
),
SCMID
(
4
),
SCMID
(
5
),
SCMID
(
5
),
pixel
,
width
);
#if defined(__GNUC__) && defined(__i386__)
scale2x_mmx_emms
();
#endif
}
/**
* Apply the Scale4x effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
* \note This function operates like ::scale4x_buf() but the intermediate buffer is
* automatically allocated in the stack.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static
void
scale4x
(
void
*
void_dst
,
unsigned
dst_slice
,
const
void
*
void_src
,
unsigned
src_slice
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
)
{
unsigned
mid_slice
;
void
*
mid
;
mid_slice
=
2
*
pixel
*
width
;
/* required space for 1 row buffer */
mid_slice
=
(
mid_slice
+
0x7
)
&
~
0x7
;
/* align to 8 bytes */
#if HAVE_ALLOCA
mid
=
alloca
(
6
*
mid_slice
);
/* allocate space for 6 row buffers */
assert
(
mid
!=
0
);
/* alloca should never fails */
#else
mid
=
malloc
(
6
*
mid_slice
);
/* allocate space for 6 row buffers */
if
(
!
mid
)
return
;
#endif
scale4x_buf
(
void_dst
,
dst_slice
,
mid
,
mid_slice
,
void_src
,
src_slice
,
pixel
,
width
,
height
);
#if !HAVE_ALLOCA
free
(
mid
);
#endif
}
/**
* Check if the scale implementation is applicable at the given arguments.
* \param scale Scale factor. 2, 203 (fox 2x3), 204 (for 2x4), 3 or 4.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
* \return
* - -1 on precondition violated.
* - 0 on success.
*/
int
scale_precondition
(
unsigned
scale
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
)
{
if
(
pixel
!=
1
&&
pixel
!=
2
&&
pixel
!=
4
)
return
-
1
;
switch
(
scale
)
{
case
202
:
case
203
:
case
204
:
case
2
:
case
303
:
case
3
:
if
(
height
<
2
)
return
-
1
;
break
;
case
404
:
case
4
:
if
(
height
<
4
)
return
-
1
;
break
;
default:
return
-
1
;
}
if
(
width
<
2
)
return
-
1
;
return
0
;
}
/**
* Apply the Scale effect on a bitmap.
* This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
* \param scale Scale factor. 2, 203 (fox 2x3), 204 (for 2x4), 3 or 4.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
void
scale
(
unsigned
scale
,
void
*
void_dst
,
unsigned
dst_slice
,
const
void
*
void_src
,
unsigned
src_slice
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
)
{
switch
(
scale
)
{
case
202
:
case
2
:
scale2x
(
void_dst
,
dst_slice
,
void_src
,
src_slice
,
pixel
,
width
,
height
);
break
;
case
203
:
scale2x3
(
void_dst
,
dst_slice
,
void_src
,
src_slice
,
pixel
,
width
,
height
);
break
;
case
204
:
scale2x4
(
void_dst
,
dst_slice
,
void_src
,
src_slice
,
pixel
,
width
,
height
);
break
;
case
303
:
case
3
:
scale3x
(
void_dst
,
dst_slice
,
void_src
,
src_slice
,
pixel
,
width
,
height
);
break
;
case
404
:
case
4
:
scale4x
(
void_dst
,
dst_slice
,
void_src
,
src_slice
,
pixel
,
width
,
height
);
break
;
}
}
src/scale2x/scalebit.h
deleted
100755 → 0
View file @
9d436013
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2003 Andrea Mazzoleni
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file contains an example implementation of the Scale effect
* applyed to a generic bitmap.
*
* You can find an high level description of the effect at :
*
* http://scale2x.sourceforge.net/
*
* Alternatively at the previous license terms, you are allowed to use this
* code in your program with these conditions:
* - the program is not used in commercial activities.
* - the whole source code of the program is released with the binary.
* - derivative works of the program are allowed.
*/
#ifndef __SCALEBIT_H
#define __SCALEBIT_H
int
scale_precondition
(
unsigned
scale
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
);
void
scale
(
unsigned
scale
,
void
*
void_dst
,
unsigned
dst_slice
,
const
void
*
void_src
,
unsigned
src_slice
,
unsigned
pixel
,
unsigned
width
,
unsigned
height
);
void
Simple2x
(
unsigned
char
*
srcPtr
,
unsigned
int
srcPitch
,
unsigned
char
*
deltaPtr
,
unsigned
char
*
dstPtr
,
unsigned
int
dstPitch
,
int
width
,
int
height
);
#endif
src/scale2x/simple2x.cpp
deleted
100755 → 0
View file @
9d436013
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/*
* Code adapted To openjazz by Pickle (from Openbor adapted by SX
* simple2x.c - Trying to scale 2x.
*
*
*/
#include "scalebit.h"
void
Simple2x
(
unsigned
char
*
srcPtr
,
unsigned
int
srcPitch
,
unsigned
char
*
deltaPtr
,
unsigned
char
*
dstPtr
,
unsigned
int
dstPitch
,
int
width
,
int
height
)
{
unsigned
char
*
nextLine
,
*
finish
;
nextLine
=
dstPtr
+
dstPitch
;
do
{
unsigned
char
*
bP
=
(
unsigned
char
*
)
srcPtr
;
unsigned
char
*
dP
=
(
unsigned
char
*
)
dstPtr
;
unsigned
char
*
nL
=
(
unsigned
char
*
)
nextLine
;
unsigned
char
currentPixel
;
finish
=
(
unsigned
char
*
)
bP
+
((
width
+
2
)
<<
1
);
currentPixel
=
*
bP
++
;
do
{
#ifdef BIG_ENDIAN
unsigned
char
color
=
currentPixel
>>
16
;
#else
unsigned
char
color
=
currentPixel
&
0xffff
;
#endif
color
=
color
|
(
color
<<
16
);
*
(
dP
)
=
color
;
*
(
nL
)
=
color
;
//#ifdef BIG_ENDIAN
// color = currentPixel & 0xffff;
//#else
// color = currentPixel >> 16;
//#endif
color
=
color
|
(
color
<<
16
);
*
(
dP
+
1
)
=
color
;
*
(
nL
+
1
)
=
color
;
currentPixel
=
*
bP
++
;
dP
+=
2
;
nL
+=
2
;
}
while
((
unsigned
char
*
)
bP
<
finish
);
srcPtr
+=
srcPitch
;
dstPtr
+=
dstPitch
<<
1
;
nextLine
+=
dstPitch
<<
1
;
}
while
(
--
height
);
}
void
Simple2x32
(
unsigned
char
*
srcPtr
,
unsigned
int
srcPitch
,
unsigned
char
*
deltaPtr
,
unsigned
char
*
dstPtr
,
unsigned
int
dstPitch
,
int
width
,
int
height
)
{
unsigned
char
*
nextLine
,
*
finish
;
nextLine
=
dstPtr
+
dstPitch
;
do
{
unsigned
int
*
bP
=
(
unsigned
int
*
)
srcPtr
;
unsigned
int
*
dP
=
(
unsigned
int
*
)
dstPtr
;
unsigned
int
*
nL
=
(
unsigned
int
*
)
nextLine
;
unsigned
int
currentPixel
;
finish
=
(
unsigned
char
*
)
bP
+
((
width
+
1
)
<<
2
);
currentPixel
=
*
bP
++
;
do
{
unsigned
int
color
=
currentPixel
;
*
(
dP
)
=
color
;
*
(
dP
+
1
)
=
color
;
*
(
nL
)
=
color
;
*
(
nL
+
1
)
=
color
;
currentPixel
=
*
bP
++
;
dP
+=
2
;
nL
+=
2
;
}
while
((
unsigned
char
*
)
bP
<
finish
);
srcPtr
+=
srcPitch
;
dstPtr
+=
dstPitch
<<
1
;
nextLine
+=
dstPitch
<<
1
;
}
while
(
--
height
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment