add scale3x, hq2x, hq3x
This commit is contained in:
parent
46e66959a3
commit
908670c2e1
14 changed files with 6915 additions and 4 deletions
|
@ -55,6 +55,7 @@ include_directories(
|
|||
src/include
|
||||
src/guichan/include
|
||||
src/guichan/include/guichan
|
||||
src/third_party/hqx/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
|
@ -338,7 +339,12 @@ set(video_SRCS
|
|||
src/video/sdl.cpp
|
||||
src/video/video.cpp
|
||||
)
|
||||
source_group(video FILES ${video_SRCS})
|
||||
set(hqx_SRCS
|
||||
src/third_party/hqx/source/HQx.cc
|
||||
src/third_party/hqx/source/HQ2x.cc
|
||||
src/third_party/hqx/source/HQ3x.cc
|
||||
)
|
||||
source_group(video FILES ${video_SRCS} ${hqx_SRCS})
|
||||
|
||||
set(win32_SRCS
|
||||
src/win32/SetupConsole_win32.cpp
|
||||
|
@ -389,6 +395,7 @@ set(stratagus_SRCS
|
|||
${ui_SRCS}
|
||||
${unit_SRCS}
|
||||
${video_SRCS}
|
||||
${hqx_SRCS}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tolua.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -211,6 +211,9 @@ struct EventCallback {
|
|||
|
||||
extern void* NullScaler(SDL_Surface *pixels);
|
||||
extern void* Epx_Scale2x_AdvMame2x_Scaler(SDL_Surface *pixels);
|
||||
extern void* Scale3x_AdvMame3x_Scaler(SDL_Surface *pixels);
|
||||
extern void* Hq2x_Scaler(SDL_Surface *pixels);
|
||||
extern void* Hq3x_Scaler(SDL_Surface *pixels);
|
||||
|
||||
class CVideo
|
||||
{
|
||||
|
|
|
@ -606,6 +606,15 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters)
|
|||
if (!strcmp(optarg, "scale2x")) {
|
||||
Video.Scale = 2;
|
||||
Video.Scaler = Epx_Scale2x_AdvMame2x_Scaler;
|
||||
} else if (!strcmp(optarg, "scale3x")) {
|
||||
Video.Scale = 3;
|
||||
Video.Scaler = Scale3x_AdvMame3x_Scaler;
|
||||
} else if (!strcmp(optarg, "hq2x")) {
|
||||
Video.Scale = 2;
|
||||
Video.Scaler = Hq2x_Scaler;
|
||||
} else if (!strcmp(optarg, "hq3x")) {
|
||||
Video.Scale = 3;
|
||||
Video.Scaler = Hq3x_Scaler;
|
||||
}
|
||||
continue;
|
||||
case -1:
|
||||
|
|
27
src/third_party/hqx/CMakeLists.txt
vendored
Normal file
27
src/third_party/hqx/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
project(hqx)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
include_directories(
|
||||
"include")
|
||||
|
||||
file(GLOB HQX_SOURCES
|
||||
"source/HQx.cc"
|
||||
"source/HQ2x.cc"
|
||||
"source/HQ3x.cc")
|
||||
|
||||
add_library(hqx ${HQX_SOURCES})
|
||||
set_target_properties(hqx PROPERTIES
|
||||
OUTPUT_NAME "hqx"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
PREFIX "lib" )
|
||||
|
||||
add_executable(test "source/main.cc")
|
||||
target_link_libraries(test hqx)
|
||||
set_target_properties(test PROPERTIES
|
||||
OUTPUT_NAME "test"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
201
src/third_party/hqx/LICENSE
vendored
Normal file
201
src/third_party/hqx/LICENSE
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
37
src/third_party/hqx/README.md
vendored
Normal file
37
src/third_party/hqx/README.md
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
C++ implementation of hq2x and hq3x scaling algorithms. This implementation was made using [DOSBOX](http://www.dosbox.com/) and [hqxSharp](https://bitbucket.org/Tamschi/hqxsharp) as reference.
|
||||
|
||||
## Algorithm
|
||||
|
||||
The hqx algorithms ("hq" stands for "high quality" and "x" stands for magnification) is a scaling algorithms created by Maxim Stepin and it's mostly used in emulators.
|
||||
|
||||
The algorithm description from [Wikipedia](https://en.wikipedia.org/wiki/Hqx):
|
||||
|
||||
> First, the color of each of the 8 pixels around the source pixel is compared to the color of the source pixel. Shapes are detected by checking for pixels of similar color according to a threshold. This gives total of 28 = 256 combinations of similar or dissimilar neighbors. To expand the single pixel into a 2×2, 3×3, or 4×4 block of pixels, the arrangement of neighbors is looked up in a predefined table which contains the necessary interpolation patterns.
|
||||
|
||||
For more information, check out the archived version of the original Maxim Stepin website: [HiEnd3D - Demos & Docs](https://web.archive.org/web/20131105130843/http://www.hiend3d.com/demos.html).
|
||||
|
||||
## Versions
|
||||
|
||||
There are two "versions" of the HQx algorithm: one to produce a sharper output and another for a smoothed output. Check out the file `HQx.cc` for more information.
|
||||
|
||||
## Samples
|
||||
|
||||
Original test image:
|
||||
|
||||
![Original](samples/test-image.bmp)
|
||||
|
||||
Test image scaled by 2x (smoothed version):
|
||||
|
||||
![Original](samples/test-image-hq2x.bmp)
|
||||
|
||||
Test image scaled by 3x (smoothed version):
|
||||
|
||||
![Original](samples/test-image-hq3x.bmp)
|
||||
|
||||
Prince of Persia 1 screenshot:
|
||||
|
||||
![Original](samples/prince.bmp)
|
||||
|
||||
Prince of Persia 1 screenshot scaled by 2x (sharper version):
|
||||
|
||||
![Original](samples/prince-hq2x.bmp)
|
46
src/third_party/hqx/include/hqx/HQ2x.hh
vendored
Normal file
46
src/third_party/hqx/include/hqx/HQ2x.hh
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2016 Bruno Ribeiro
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef HQX_HQ2X_HH
|
||||
#define HQX_HQ2X_HH
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <hqx/HQx.hh>
|
||||
|
||||
|
||||
class HQ2x : public HQx
|
||||
{
|
||||
public:
|
||||
HQ2x();
|
||||
|
||||
~HQ2x();
|
||||
|
||||
uint32_t *resize(
|
||||
const uint32_t *image,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t *output,
|
||||
uint32_t trY = 0x30,
|
||||
uint32_t trU = 0x07,
|
||||
uint32_t trV = 0x06,
|
||||
uint32_t trA = 0x50,
|
||||
bool wrapX = false,
|
||||
bool wrapY = false ) const;
|
||||
};
|
||||
|
||||
|
||||
#endif // HQX_HQ2X_HH
|
46
src/third_party/hqx/include/hqx/HQ3x.hh
vendored
Normal file
46
src/third_party/hqx/include/hqx/HQ3x.hh
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2016 Bruno Ribeiro
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef HQX_HQ3X_HH
|
||||
#define HQX_HQ3X_HH
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <hqx/HQx.hh>
|
||||
|
||||
|
||||
class HQ3x : public HQx
|
||||
{
|
||||
public:
|
||||
HQ3x();
|
||||
|
||||
~HQ3x();
|
||||
|
||||
uint32_t *resize(
|
||||
const uint32_t *image,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t *output,
|
||||
uint32_t trY = 0x30,
|
||||
uint32_t trU = 0x07,
|
||||
uint32_t trV = 0x06,
|
||||
uint32_t trA = 0x50,
|
||||
bool wrapX = false,
|
||||
bool wrapY = false ) const;
|
||||
};
|
||||
|
||||
|
||||
#endif // HQX_HQ3X_HH
|
171
src/third_party/hqx/include/hqx/HQx.hh
vendored
Normal file
171
src/third_party/hqx/include/hqx/HQx.hh
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright 2016 Bruno Ribeiro
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef HQX_HQX_HH
|
||||
#define HQX_HQX_HH
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define MASK_RB 0x00FF00FF
|
||||
#define MASK_G 0x0000FF00
|
||||
#define MASK_A 0xFF000000
|
||||
|
||||
|
||||
/**
|
||||
* @brief Mixes two colors using the given weights.
|
||||
*/
|
||||
#define HQX_MIX_2(C0,C1,W0,W1) \
|
||||
((((C0 & MASK_RB) * W0 + (C1 & MASK_RB) * W1) / (W0 + W1)) & MASK_RB) | \
|
||||
((((C0 & MASK_G) * W0 + (C1 & MASK_G) * W1) / (W0 + W1)) & MASK_G) | \
|
||||
((((((C0 & MASK_A) >> 8) * W0 + ((C1 & MASK_A) >> 8) * W1) / (W0 + W1)) << 8) & MASK_A)
|
||||
|
||||
/**
|
||||
* @brief Mixes three colors using the given weights.
|
||||
*/
|
||||
#define HQX_MIX_3(C0,C1,C2,W0,W1,W2) \
|
||||
((((C0 & MASK_RB) * W0 + (C1 & MASK_RB) * W1 + (C2 & MASK_RB) * W2) / (W0 + W1 + W2)) & MASK_RB) | \
|
||||
((((C0 & MASK_G) * W0 + (C1 & MASK_G) * W1 + (C2 & MASK_G) * W2) / (W0 + W1 + W2)) & MASK_G) | \
|
||||
((((((C0 & MASK_A) >> 8) * W0 + ((C1 & MASK_A) >> 8) * W1 + ((C2 & MASK_A) >> 8) * W2) / (W0 + W1 + W2)) << 8) & MASK_A)
|
||||
|
||||
|
||||
#define MIX_00_4 *output = w[4];
|
||||
#define MIX_00_4_0_3_1 *output = HQX_MIX_2(w[4],w[0],3U,1U);
|
||||
#define MIX_00_4_3_3_1 *output = HQX_MIX_2(w[4],w[3],3U,1U);
|
||||
#define MIX_00_4_1_3_1 *output = HQX_MIX_2(w[4],w[1],3U,1U);
|
||||
#define MIX_00_3_1_1_1 *output = HQX_MIX_2(w[3],w[1],1U,1U);
|
||||
#define MIX_00_4_3_1_2_1_1 *output = HQX_MIX_3(w[4],w[3],w[1],2U,1U,1U);
|
||||
#define MIX_00_4_3_1_2_7_7 *output = HQX_MIX_3(w[4],w[3],w[1],2U,7U,7U);
|
||||
#define MIX_00_4_0_1_2_1_1 *output = HQX_MIX_3(w[4],w[0],w[1],2U,1U,1U);
|
||||
#define MIX_00_4_0_3_2_1_1 *output = HQX_MIX_3(w[4],w[0],w[3],2U,1U,1U);
|
||||
#define MIX_00_4_1_3_5_2_1 *output = HQX_MIX_3(w[4],w[1],w[3],5U,2U,1U);
|
||||
#define MIX_00_4_3_1_5_2_1 *output = HQX_MIX_3(w[4],w[3],w[1],5U,2U,1U);
|
||||
#define MIX_00_4_3_1_6_1_1 *output = HQX_MIX_3(w[4],w[3],w[1],6U,1U,1U);
|
||||
#define MIX_00_4_3_1_2_3_3 *output = HQX_MIX_3(w[4],w[3],w[1],2U,3U,3U);
|
||||
#define MIX_00_4_3_1_e_1_1 *output = HQX_MIX_3(w[4],w[3],w[1],14U,1U,1U);
|
||||
|
||||
#define MIX_01_4 *(output + 1) = w[4];
|
||||
#define MIX_01_4_2_3_1 *(output + 1) = HQX_MIX_2(w[4],w[2],3U,1U);
|
||||
#define MIX_01_4_1_3_1 *(output + 1) = HQX_MIX_2(w[4],w[1],3U,1U);
|
||||
#define MIX_01_1_4_3_1 *(output + 1) = HQX_MIX_2(w[1],w[4],3U,1U);
|
||||
#define MIX_01_4_5_3_1 *(output + 1) = HQX_MIX_2(w[4],w[5],3U,1U);
|
||||
#define MIX_01_4_1_7_1 *(output + 1) = HQX_MIX_2(w[4],w[1],7U,1U);
|
||||
#define MIX_01_4_1_5_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],2U,1U,1U);
|
||||
#define MIX_01_4_2_5_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[2],w[5],2U,1U,1U);
|
||||
#define MIX_01_4_2_1_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[2],w[1],2U,1U,1U);
|
||||
#define MIX_01_4_5_1_5_2_1 *(output + 1) = HQX_MIX_3(w[4],w[5],w[1],5U,2U,1U);
|
||||
#define MIX_01_4_1_5_5_2_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],5U,2U,1U);
|
||||
#define MIX_01_4_1_5_6_1_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],6U,1U,1U);
|
||||
#define MIX_01_4_1_5_2_3_3 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],2U,3U,3U);
|
||||
#define MIX_01_4_1_5_e_1_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],14U,1U,1U);
|
||||
|
||||
#define MIX_02_4 *(output + 2) = w[4];
|
||||
#define MIX_02_4_2_3_1 *(output + 2) = HQX_MIX_2(w[4],w[2],3U,1U);
|
||||
#define MIX_02_4_1_3_1 *(output + 2) = HQX_MIX_2(w[4],w[1],3U,1U);
|
||||
#define MIX_02_4_5_3_1 *(output + 2) = HQX_MIX_2(w[4],w[5],3U,1U);
|
||||
#define MIX_02_4_1_5_2_1_1 *(output + 2) = HQX_MIX_3(w[4],w[1],w[5],2U,1U,1U);
|
||||
#define MIX_02_4_1_5_2_7_7 *(output + 2) = HQX_MIX_3(w[4],w[1],w[5],2U,7U,7U);
|
||||
#define MIX_02_1_5_1_1 *(output + 2) = HQX_MIX_2(w[1],w[5],1U,1U);
|
||||
|
||||
#define MIX_10_4 *(output + lineSize) = w[4];
|
||||
#define MIX_10_4_6_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[6],3U,1U);
|
||||
#define MIX_10_4_7_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[7],3U,1U);
|
||||
#define MIX_10_4_3_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[3],3U,1U);
|
||||
#define MIX_10_4_7_3_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,1U,1U);
|
||||
#define MIX_10_4_6_3_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[6],w[3],2U,1U,1U);
|
||||
#define MIX_10_4_6_7_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[6],w[7],2U,1U,1U);
|
||||
#define MIX_10_4_3_7_5_2_1 *(output + lineSize) = HQX_MIX_3(w[4],w[3],w[7],5U,2U,1U);
|
||||
#define MIX_10_4_7_3_5_2_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],5U,2U,1U);
|
||||
#define MIX_10_4_7_3_6_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],6U,1U,1U);
|
||||
#define MIX_10_4_7_3_2_3_3 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,3U,3U);
|
||||
#define MIX_10_4_7_3_e_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],14U,1U,1U);
|
||||
#define MIX_10_4_3_7_1 *(output + lineSize) = HQX_MIX_2(w[4],w[3],7U,1U);
|
||||
#define MIX_10_3_4_3_1 *(output + lineSize) = HQX_MIX_2(w[3],w[4],3U,1U);
|
||||
|
||||
#define MIX_11_4 *(output + lineSize + 1) = w[4];
|
||||
#define MIX_11_4_8_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[8],3U,1U);
|
||||
#define MIX_11_4_5_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[5],3U,1U);
|
||||
#define MIX_11_4_7_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[7],3U,1U);
|
||||
#define MIX_11_4_5_7_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],2U,1U,1U);
|
||||
#define MIX_11_4_8_7_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[8],w[7],2U,1U,1U);
|
||||
#define MIX_11_4_8_5_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[8],w[5],2U,1U,1U);
|
||||
#define MIX_11_4_7_5_5_2_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[7],w[5],5U,2U,1U);
|
||||
#define MIX_11_4_5_7_5_2_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],5U,2U,1U);
|
||||
#define MIX_11_4_5_7_6_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],6U,1U,1U);
|
||||
#define MIX_11_4_5_7_2_3_3 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],2U,3U,3U);
|
||||
#define MIX_11_4_5_7_e_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],14U,1U,1U);
|
||||
|
||||
#define MIX_12_4 *(output + lineSize + 2) = w[4];
|
||||
#define MIX_12_4_5_3_1 *(output + lineSize + 2) = HQX_MIX_2(w[4],w[5],3U,1U);
|
||||
#define MIX_12_4_5_7_1 *(output + lineSize + 2) = HQX_MIX_2(w[4],w[5],7U,1U);
|
||||
#define MIX_12_5_4_3_1 *(output + lineSize + 2) = HQX_MIX_2(w[5],w[4],3U,1U);
|
||||
|
||||
#define MIX_20_4 *(output + lineSize + lineSize) = w[4];
|
||||
#define MIX_20_4_6_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[6],3U,1U);
|
||||
#define MIX_20_4_7_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[7],3U,1U);
|
||||
#define MIX_20_4_3_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[3],3U,1U);
|
||||
#define MIX_20_4_7_3_2_1_1 *(output + lineSize + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,1U,1U);
|
||||
#define MIX_20_4_7_3_2_7_7 *(output + lineSize + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,7U,7U);
|
||||
#define MIX_20_7_3_1_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[7],w[3],1U,1U);
|
||||
|
||||
#define MIX_21_4 *(output + lineSize + lineSize + 1) = w[4];
|
||||
#define MIX_21_4_7_3_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[4],w[7],3U,1U);
|
||||
#define MIX_21_4_7_7_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[4],w[7],7U,1U);
|
||||
#define MIX_21_7_4_3_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[7],w[4],3U,1U);
|
||||
|
||||
#define MIX_22_4 *(output + lineSize + lineSize + 2) = w[4];
|
||||
#define MIX_22_4_8_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[8],3U,1U);
|
||||
#define MIX_22_4_7_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[7],3U,1U);
|
||||
#define MIX_22_4_5_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[5],3U,1U);
|
||||
#define MIX_22_4_5_7_2_1_1 *(output + lineSize + lineSize + 2) = HQX_MIX_3(w[4],w[5],w[7],2U,1U,1U);
|
||||
#define MIX_22_4_5_7_2_7_7 *(output + lineSize + lineSize + 2) = HQX_MIX_3(w[4],w[5],w[7],2U,7U,7U);
|
||||
#define MIX_22_5_7_1_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[5],w[7],1U,1U);
|
||||
|
||||
|
||||
class HQx
|
||||
{
|
||||
public:
|
||||
HQx();
|
||||
|
||||
virtual ~HQx();
|
||||
|
||||
static uint32_t ARGBtoAYUV(
|
||||
uint32_t value );
|
||||
|
||||
virtual uint32_t *resize(
|
||||
const uint32_t *image,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t *output,
|
||||
uint32_t trY = 0x40,
|
||||
uint32_t trU = 0x07,
|
||||
uint32_t trV = 0x06,
|
||||
uint32_t trA = 0x50,
|
||||
bool wrapX = false,
|
||||
bool wrapY = false ) const = 0;
|
||||
|
||||
static bool isDifferent(
|
||||
uint32_t yuv1,
|
||||
uint32_t yuv2,
|
||||
uint32_t trY,
|
||||
uint32_t trU,
|
||||
uint32_t trV,
|
||||
uint32_t trA );
|
||||
};
|
||||
|
||||
|
||||
#endif // HQX_HQX_HH
|
2471
src/third_party/hqx/source/HQ2x.cc
vendored
Normal file
2471
src/third_party/hqx/source/HQ2x.cc
vendored
Normal file
File diff suppressed because it is too large
Load diff
3456
src/third_party/hqx/source/HQ3x.cc
vendored
Normal file
3456
src/third_party/hqx/source/HQ3x.cc
vendored
Normal file
File diff suppressed because it is too large
Load diff
112
src/third_party/hqx/source/HQx.cc
vendored
Normal file
112
src/third_party/hqx/source/HQx.cc
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 2016 Bruno Ribeiro
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hqx/HQx.hh>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
static const uint32_t AMASK = 0xFF000000;
|
||||
static const uint32_t YMASK = 0x00FF0000;
|
||||
static const uint32_t UMASK = 0x0000FF00;
|
||||
static const uint32_t VMASK = 0x000000FF;
|
||||
|
||||
HQx::HQx()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
||||
HQx::~HQx()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
||||
uint32_t HQx::ARGBtoAYUV(
|
||||
uint32_t value )
|
||||
{
|
||||
uint32_t A, R, G, B, Y, U, V;
|
||||
|
||||
A = value >> 24;
|
||||
R = (value >> 16) & 0xFF;
|
||||
G = (value >> 8) & 0xFF;
|
||||
B = value & 0xFF;
|
||||
|
||||
Y = (uint32_t) ( 0.299 * R + 0.587 * G + 0.114 * B);
|
||||
U = (uint32_t) (-0.169 * R - 0.331 * G + 0.5 * B) + 128;
|
||||
V = (uint32_t) ( 0.5 * R - 0.419 * G - 0.081 * B) + 128;
|
||||
return (A << 24) + (Y << 16) + (U << 8) + V;
|
||||
}
|
||||
|
||||
|
||||
#if (1)
|
||||
|
||||
/*
|
||||
* Use this function for sharper images (good for cartoon style, used by DOSBOX)
|
||||
*/
|
||||
|
||||
bool HQx::isDifferent(
|
||||
uint32_t color1,
|
||||
uint32_t color2,
|
||||
uint32_t trY,
|
||||
uint32_t trU,
|
||||
uint32_t trV,
|
||||
uint32_t trA )
|
||||
{
|
||||
color1 = ARGBtoAYUV(color1);
|
||||
color2 = ARGBtoAYUV(color2);
|
||||
|
||||
uint32_t value;
|
||||
|
||||
value = abs(int(color1 & YMASK) - int(color2 & YMASK));
|
||||
if (value > trY) return true;
|
||||
|
||||
value = abs(int(color1 & UMASK) - int(color2 & UMASK));
|
||||
if (value > trU) return true;
|
||||
|
||||
value = abs(int(color1 & VMASK) - int(color2 & VMASK));
|
||||
if (value > trV) return true;
|
||||
|
||||
value = abs(int(color1 & AMASK) - int(color2 & AMASK));
|
||||
if (value > trA) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Use this function for smoothed images (good for complex graphics)
|
||||
*/
|
||||
|
||||
bool HQx::isDifferent(
|
||||
uint32_t color1,
|
||||
uint32_t color2,
|
||||
uint32_t trY,
|
||||
uint32_t trU,
|
||||
uint32_t trV,
|
||||
uint32_t trA )
|
||||
{
|
||||
uint32_t yuv1 = ARGBtoAYUV(color1);
|
||||
uint32_t yuv2 = ARGBtoAYUV(color2);
|
||||
|
||||
return abs(int(yuv1 & YMASK) - int(yuv2 & YMASK)) > trY ||
|
||||
abs(int(yuv1 & UMASK) - int(yuv2 & UMASK)) > trU ||
|
||||
abs(int(yuv1 & VMASK) - int(yuv2 & VMASK)) > trV ||
|
||||
abs(int(yuv1 & AMASK) - int(yuv2 & AMASK)) > trA;
|
||||
}
|
||||
|
||||
#endif
|
201
src/third_party/hqx/source/main.cc
vendored
Normal file
201
src/third_party/hqx/source/main.cc
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright 2016 Bruno Ribeiro
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hqx/HQ2x.hh>
|
||||
#include <hqx/HQ3x.hh>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
using std::string;
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct BitmapHeader
|
||||
{
|
||||
uint16_t bfType;
|
||||
uint32_t bfSize;
|
||||
uint32_t bfRes1;
|
||||
uint32_t bfOffBits;
|
||||
};
|
||||
|
||||
struct DibHeader
|
||||
{
|
||||
uint32_t biSize;
|
||||
uint32_t biWidth;
|
||||
uint32_t biHeight;
|
||||
uint16_t biPlanes;
|
||||
uint16_t biBitCount;
|
||||
uint32_t biCompression;
|
||||
uint32_t biSizeImage;
|
||||
uint32_t biXPelsPerMeter;
|
||||
uint32_t biYPelsPerMeter;
|
||||
uint32_t biClrUsed;
|
||||
uint32_t biClrImportant;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Saves an Windows Bitmap image (24 BPP).
|
||||
*/
|
||||
int main_saveBitmap(
|
||||
const uint32_t *data,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
const string &fileName )
|
||||
{
|
||||
BitmapHeader bh;
|
||||
DibHeader dh;
|
||||
uint16_t suffix;
|
||||
uint32_t zero = 0;
|
||||
const uint32_t *ptr;
|
||||
|
||||
ofstream output(fileName.c_str(), std::ios_base::binary);
|
||||
if (!output.good()) return -1;
|
||||
|
||||
suffix = ((width + 3) & ~0x03) - width;
|
||||
|
||||
dh.biSize = sizeof(DibHeader);
|
||||
dh.biWidth = width;
|
||||
dh.biHeight = height;
|
||||
dh.biPlanes = 1;
|
||||
dh.biBitCount = 24;
|
||||
dh.biCompression = 0;
|
||||
dh.biSizeImage = (uint16_t) ( (width*3+suffix)*height );
|
||||
dh.biXPelsPerMeter = 0x2E23;
|
||||
dh.biYPelsPerMeter = dh.biXPelsPerMeter;
|
||||
dh.biClrUsed = 0;
|
||||
dh.biClrImportant = 0;
|
||||
|
||||
bh.bfType = 0x4D42;
|
||||
bh.bfSize = dh.biSizeImage + 0x0036;
|
||||
bh.bfRes1 = 0;
|
||||
bh.bfOffBits = 0x0036;
|
||||
output.write( (char*) &bh, sizeof(BitmapHeader) );
|
||||
output.write( (char*) &dh, sizeof(DibHeader) );
|
||||
|
||||
ptr = data + (width * height);
|
||||
for (uint32_t i = 0; i < height; i++)
|
||||
{
|
||||
ptr -= width;
|
||||
|
||||
for (uint32_t j = 0; j < width; ++j)
|
||||
output.write( (char*) (ptr + j), 3 );
|
||||
|
||||
if (suffix > 0)
|
||||
output.write( (char*) &zero, suffix );
|
||||
}
|
||||
|
||||
output.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Loads an Windows Bitmap image (24 BPP).
|
||||
*/
|
||||
int main_loadBitmap(
|
||||
const string &fileName,
|
||||
uint32_t *&data,
|
||||
uint16_t &width,
|
||||
uint16_t &height )
|
||||
{
|
||||
BitmapHeader bh;
|
||||
DibHeader dh;
|
||||
uint16_t suffix;
|
||||
uint32_t zero = 0;
|
||||
uint32_t *ptr;
|
||||
uint16_t bits;
|
||||
|
||||
ifstream input(fileName.c_str(), std::ios_base::binary);
|
||||
if (!input.good()) return -1;
|
||||
|
||||
input.read( (char*) &bh, sizeof(BitmapHeader) );
|
||||
if (bh.bfType != 0x4D42) return -1;
|
||||
input.read( (char*) &dh.biSize, sizeof(uint32_t) );
|
||||
if (dh.biSize != 40) return -1;
|
||||
|
||||
input.read( (char*) &dh.biWidth, sizeof(DibHeader) - sizeof(uint32_t) );
|
||||
width = dh.biWidth;
|
||||
height = dh.biHeight;
|
||||
if (dh.biBitCount != 24) return -1;
|
||||
|
||||
suffix = ((width + 3) & ~0x03) - width;
|
||||
ptr = data = new uint32_t[width * height]();
|
||||
ptr += width * height;
|
||||
for (uint32_t i = 0; i < height; i++)
|
||||
{
|
||||
ptr -= width;
|
||||
|
||||
for (uint32_t j = 0; j < width; ++j)
|
||||
{
|
||||
input.read( (char*) (ptr + j), 3 );
|
||||
*(ptr + j) |= 0xFF000000;
|
||||
}
|
||||
|
||||
if (suffix > 0)
|
||||
input.read( (char*) &zero, suffix );
|
||||
}
|
||||
|
||||
input.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv )
|
||||
{
|
||||
uint32_t factor = 2;
|
||||
|
||||
if (argc != 2 && argc != 3) return 1;
|
||||
if (argc == 3) factor = atoi(argv[2]);
|
||||
|
||||
// loads the input image
|
||||
uint16_t width, height;
|
||||
uint32_t *image = NULL;
|
||||
if ( main_loadBitmap(argv[1], image, width, height) != 0) return 1;
|
||||
std::cout << "Resizing '" << argv[1] << "' [" << width << "x" << height << "] by " <<
|
||||
factor << 'x' << std::endl;
|
||||
|
||||
clock_t t = clock();
|
||||
|
||||
// resize the input image using the given scale factor
|
||||
uint32_t outputSize = (width * factor) * (height * factor);
|
||||
uint32_t *output = new uint32_t[outputSize]();
|
||||
HQx *scale;
|
||||
if (factor == 2)
|
||||
scale = new HQ2x();
|
||||
else
|
||||
scale = new HQ3x();
|
||||
scale->resize(image, width, height, output);
|
||||
delete scale;
|
||||
|
||||
t = clock() - t;
|
||||
std::cout << "Processing time: " << t / (CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
|
||||
|
||||
// saves the resized image
|
||||
if ( main_saveBitmap(output, width * factor, height * factor, "output.bmp") != 0 ) return 1;
|
||||
|
||||
delete[] image;
|
||||
delete[] output;
|
||||
}
|
|
@ -93,6 +93,8 @@
|
|||
#include "map.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "hqx/HQ2x.hh"
|
||||
#include "hqx/HQ3x.hh"
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
|
@ -290,7 +292,7 @@ bool CVideo::ResizeScreen(int w, int h)
|
|||
0x000000ff,
|
||||
0); // 0xff000000);
|
||||
Assert(SDL_MUSTLOCK(TheScreen) == 0);
|
||||
TheScreen->userdata = calloc(w * Video.Scale * h * Video.Scale, sizeof(Uint32));
|
||||
TheScreen->userdata = calloc(w * Scale * h * Scale, sizeof(Uint32));
|
||||
|
||||
// new texture
|
||||
if (TheTexture) {
|
||||
|
@ -299,7 +301,7 @@ bool CVideo::ResizeScreen(int w, int h)
|
|||
TheTexture = SDL_CreateTexture(TheRenderer,
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
w * Video.Scale, h * Video.Scale);
|
||||
w * Scale, h * Scale);
|
||||
|
||||
SetClipping(0, 0, w - 1, h - 1);
|
||||
|
||||
|
@ -488,7 +490,6 @@ void* NullScaler(SDL_Surface *s) {
|
|||
void* Epx_Scale2x_AdvMame2x_Scaler(SDL_Surface *s) {
|
||||
Assert(Video.Scale == 2);
|
||||
Assert(s->format->BitsPerPixel == 32);
|
||||
Assert(Video.Height * Video.Width == s->h * 2 * s->w * 2);
|
||||
|
||||
Uint32 *in = (Uint32*) s->pixels;
|
||||
Uint32 *out = (Uint32*) s->userdata;
|
||||
|
@ -540,6 +541,129 @@ void* Epx_Scale2x_AdvMame2x_Scaler(SDL_Surface *s) {
|
|||
return out;
|
||||
}
|
||||
|
||||
void* Scale3x_AdvMame3x_Scaler(SDL_Surface *s) {
|
||||
Assert(Video.Scale == 3);
|
||||
Assert(s->format->BitsPerPixel == 32);
|
||||
|
||||
Uint32 *in = (Uint32*) s->pixels;
|
||||
Uint32 *out = (Uint32*) s->userdata;
|
||||
int inputW = s->w;
|
||||
int outputW = s->w * 3;
|
||||
|
||||
// Just the algo from wikipedia.
|
||||
//
|
||||
// Input +-----+-----+-----+
|
||||
// | A | B | C |
|
||||
// +-----+-----+-----+
|
||||
// | D | E | F |
|
||||
// +-----+-----+-----+
|
||||
// | G | H | I |
|
||||
// +-----+-----+-----+
|
||||
// ||
|
||||
// Output +-----+-----+-----+
|
||||
// | 1 | 2 | 3 |
|
||||
// +-----+-----+-----+
|
||||
// | 4 | 5 | 6 |
|
||||
// +-----+-----+-----+
|
||||
// | 7 | 8 | 9 |
|
||||
// +-----+-----+-----+
|
||||
Uint32 a, b, c, d, e, f, g, h, i, o1, o2, o3, o4, o5, o6, o7, o8, o9;
|
||||
for (int y = 1, y2 = 1; y < Video.Height - 1; y++, y2 += 3) {
|
||||
for (int x = 1, x2 = 1; x < Video.Width - 1; x++, x2 += 3) {
|
||||
o1 = o2 = o3 = o4 = o5 = o6 = o7 = o8 = o9 = e = in[x + y * inputW];
|
||||
a = in[x - 1 + (y - 1) * inputW];
|
||||
b = in[x + (y - 1) * inputW];
|
||||
c = in[x + 1 + (y - 1) * inputW];
|
||||
d = in[x - 1 + y * inputW];
|
||||
f = in[x + 1 + y * inputW];
|
||||
g = in[x - 1 + (y + 1) * inputW];
|
||||
h = in[x + (y + 1) * inputW];
|
||||
i = in[x + 1 + (y + 1) * inputW];
|
||||
|
||||
if (d == b && d != h && b != f) {
|
||||
o1 = d;
|
||||
if (e != c) {
|
||||
o2 = b;
|
||||
}
|
||||
if (e != g) {
|
||||
o4 = d;
|
||||
}
|
||||
}
|
||||
if (b == f && b != d && f != h) {
|
||||
o3 = f;
|
||||
if (e != a) {
|
||||
o2 = b;
|
||||
}
|
||||
if (e != i) {
|
||||
o6 = f;
|
||||
}
|
||||
}
|
||||
if (h == d && h != f && d != b) {
|
||||
o7 = d;
|
||||
if (e != a) {
|
||||
o4 = d;
|
||||
}
|
||||
if (e != i) {
|
||||
o8 = h;
|
||||
}
|
||||
}
|
||||
if (f == h && f != b && h != d) {
|
||||
o9 = f;
|
||||
if (e != c) {
|
||||
o6 = f;
|
||||
}
|
||||
if (e != g) {
|
||||
o8 = h;
|
||||
}
|
||||
}
|
||||
|
||||
out[x2 - 1 + (y2 - 1) * outputW] = o1;
|
||||
out[x2 + (y2 - 1) * outputW] = o2;
|
||||
out[x2 + 1 + (y2 - 1) * outputW] = o3;
|
||||
out[x2 - 1 + y2 * outputW] = o4;
|
||||
out[x2 + y2 * outputW] = o5;
|
||||
out[x2 + 1 + y2 * outputW] = o6;
|
||||
out[x2 - 1 + (y2 + 1) * outputW] = o7;
|
||||
out[x2 + (y2 + 1) * outputW] = o8;
|
||||
out[x2 + 1 + (y2 + 1) * outputW] = o9;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void *Hq2x_Scaler(SDL_Surface *s) {
|
||||
// these shifts are the hqx ARGBtoAYUV hardcoded values
|
||||
Assert(s->format->Ashift == 24);
|
||||
Assert(s->format->Rshift == 16);
|
||||
Assert(s->format->Gshift == 8);
|
||||
Assert(s->format->Bshift == 0);
|
||||
Assert(Video.Scale == 2);
|
||||
Assert(s->format->BitsPerPixel == 32);
|
||||
|
||||
Uint32 *in = (Uint32 *)s->pixels;
|
||||
Uint32 *out = (Uint32 *)s->userdata;
|
||||
HQ2x *hq2x = new HQ2x();
|
||||
hq2x->resize(in, Video.Width, Video.Height, out);
|
||||
delete hq2x;
|
||||
return out;
|
||||
}
|
||||
|
||||
void *Hq3x_Scaler(SDL_Surface *s) {
|
||||
// these shifts are the hqx ARGBtoAYUV hardcoded values
|
||||
Assert(s->format->Ashift == 24);
|
||||
Assert(s->format->Rshift == 16);
|
||||
Assert(s->format->Gshift == 8);
|
||||
Assert(s->format->Bshift == 0);
|
||||
Assert(Video.Scale == 3);
|
||||
Assert(s->format->BitsPerPixel == 32);
|
||||
|
||||
Uint32 *in = (Uint32 *)s->pixels;
|
||||
Uint32 *out = (Uint32 *)s->userdata;
|
||||
HQ3x *hq3x = new HQ3x();
|
||||
hq3x->resize(in, Video.Width, Video.Height, out);
|
||||
delete hq3x;
|
||||
return out;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
Loading…
Reference in a new issue