summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/ReadMe.txt138
-rw-r--r--android/build.properties17
-rw-r--r--android/build.xml77
-rw-r--r--android/default.properties11
-rw-r--r--android/jni/Core.mk3
-rw-r--r--android/jni/mupdf.c18
-rw-r--r--android/local.properties2
-rw-r--r--draw/draw_scale.c368
8 files changed, 441 insertions, 193 deletions
diff --git a/android/ReadMe.txt b/android/ReadMe.txt
index c46c88b6..7d111ece 100644
--- a/android/ReadMe.txt
+++ b/android/ReadMe.txt
@@ -1,77 +1,131 @@
To build/debug android build.
-1) Download the android sdk, and install it. On windows I unpacked it as:
+1) Download the android sdk, and install it. These instructions have been
+written with r14 (the latest version at time of writing) of the SDK in mind;
+other versions may give problems. On windows r14 unpacked as:
- C:\Program Files\android-sdk-windows
+ C:\Program Files (x86)\Android\android-sdk
-on Macos as:
+on Macos an older version installed as:
/Library/android-sdk-mac_x86
-On windows add: C:/Progra~1/android-sdk-windows/tools to your path.
-On linux/macos add the equivalent.
+Whatever directory it unpacks to, ensure that both the 'tools' and
+'platform-tools' directories inside it have been added to your PATH.
-2) Download the android ndk, and install in. On windows I unpacked it as:
+2) Download the android ndk, and unpack it. These instructions have been
+written with r6b (the latest version at the time of writing) of the NDK
+in mind; other versions may give problems. On windows I unpacked it as:
- C:\Program Files\android-ndk-r5
+ C:\android-ndk-r6b
-on Macos as:
+on Macos an older version unpacked as:
/Library/android-ndk-r5
-On windows add: C:/Progra~1/android-ndk-r5 to your path. On linux/macos
-add the equivalent.
+It is very important that you should unpack it to a directory with no
+spaces in the name! (Don't be tempted to put it in C:\Program Files etc)
+
+Ensure that that directory is also added to your PATH.
3) On windows, to use the ndk, you *must* be running under cygwin. This means
you need to install Cygwin 1.7 or greater now.
-In the current release of the ndk (r5), when running under cygwin, there are
-bugs to do with the automatic conversion of dependencies from DOS format
-paths to cygwin format paths. The 2 fixes can be found in:
-
- <http://groups.google.com/group/android-ndk/msg/b385e47e1484c2d4>
-
-4) Bring up a shell, and run 'android'. This will bring up a graphical
-gui for the sdk. From here you can install the different SDK components
-for the different flavours of android. Download them all - bandwidth and disk
-space are cheap, right?
-
-5) Now go to the Virtual Devices entry on the right hand side. You need to
-create yourself an emulator image to use. Click 'New...' on the right hand
-side and a window will appear. Fill in the entries as follows:
+[ In version r5 of the ndk, when running under cygwin, there were ]
+[ bugs to do with the automatic conversion of dependencies from DOS ]
+[ format paths to cygwin format paths. The 2 fixes can be found in: ]
+[ ]
+[ <http://groups.google.com/group/android-ndk/msg/b385e47e1484c2d4> ]
+[ ]
+[ Use the latest version and there should not be a problem. ]
+
+4) If the SDK has not popped up a window already, bring up a shell, and run
+'android' (or android.bat on cygwin/windows). You should now have a window
+with a graphical gui for the sdk. From here you can install the different SDK
+components for the different flavours of android. Download them all -
+bandwidth and disk space are cheap, right?
+
+5) In new versions of the GUI there is a 'Tools' menu from which you can
+select 'Manage AVDs...'. In old versions, go to the Virtual Devices entry
+on the right hand side. You need to create yourself an emulator image to
+use. Click 'New...' on the right hand side and a window will appear. Fill
+in the entries as follows:
Name: FroyoEm
Target: Android 2.2 - API Level 8
+ CPU/ABI: ARM (armeabi) (If this option exists)
SD card: Size: 1024MiB
Skin: Resolution: 480x756 (756 just fits my macbook screen, but 800 may
be 'more standard')
-Click 'Create AVD' and wait for a minute or so while it is prepared. Now
-you can exit the GUI.
+Click 'Create AVD' (on old versions you may have to wait for a minute or
+so while it is prepared. Now you can exit the GUI.
-6) Now we are ready to build mupdf for Android. Check out a copy of MuPDF
+6) You will need a copy of the JDK installed. See
+<http://www.oracle.com/technetwork/java/javase/downloads/>. When this
+installs, ensure that JAVA_HOME is set to point to the installation
+directory.
+
+7) You will need a copy of Apache ANT installed.
+See <http://ant.apache.org/>. Ensure that ANT_HOME is set to point to
+the top level directory, and that ANT_HOME/bin is on the PATH.
+
+8) Now we are ready to build mupdf for Android. Check out a copy of MuPDF
(but you've done that already, cos you're reading this, right?).
-7) You will also need a copy of mupdf-thirdparty.zip (see the source code
+9) You will also need a copy of mupdf-thirdparty.zip (see the source code
link on http://mupdf.com/). Unpack the contents of this into a 'thirdparty'
directory created within the mupdf directory (i.e. at the same level as
fitz, pdf, android etc).
-8) Finally, you will need a copy of a 'generated' directory. This is not
-currently available to download. The easiest way to obtain this is to do
-a standard windows or linux build of mupdf, which generates the required
-files as part of the build process.
+10) Finally, you will need a copy of a 'generated' directory. This is not
+currently available to download.
+
+The normal mupdf build process involves running some code on the host
+(the machine on which you are compiling), rather than the target (the
+machine/device on which you eventually want to run mupdf). This code
+repacks various bits of information (fonts, CMAPs etc) into a more
+compact and usable form.
+
+Unfortunately, the android SDK does not provide a compiler for the host
+machine, so we cannot run this step automatically as part of the android
+build. You will need to generate it by running a different build, such
+as the windows or linux native builds.
-9) Change into the android directory, and edit local.properties into your
+We do not make a snapshot of the generated directory available to
+download as the contents of this directory change frequently, and we'd
+have to keep multiple versions on the website. We assume that anyone
+capable of building for android is capable of doing a normal hosted
+build.
+
+On windows (where you are using cygwin), or on linux/macos, this can be
+as simple as running 'make' in the top level directory. Even if the
+make process fails, it should get far enough to generate you the required
+'generated' directory, and you can continue through these instructions.
+
+11) Change into the android directory, and edit local.properties into your
favourite editor. Change the sdk path there as appropriate. This should be
the only bit of localisation you need to do.
-10) Change into the android directory (note, the android directory, NOT
+12) Change into the android directory (note, the android directory, NOT
the android/jni directory!), and execute (in a Cygwin window on Windows!):
ndk-build
-This should build the native code portion. Then execute:
+This should build the native code portion.
+
+If this dies with an error in thirdparty/jbig2/os_types.h load this
+file into an editor, and change line 43 from:
+
+ #else
+
+to
+
+ #elif !defined(HAVE_STDINT_H)
+
+and this should solve the problem.
+
+13) Then execute:
ant debug
@@ -81,13 +135,13 @@ or on windows under cygwin:
This should build the java wrapper.
-11) Now start the emulator by executing:
+14) Now start the emulator by executing:
emulator -avd FroyoEm
This will take a while to full start up (be patient).
-12) We now need to give the demo file something to chew on, so let's copy
+15) We now need to give the demo file something to chew on, so let's copy
a file into the SD card image of the emulator (this should only need to be
done once). With the emulator running type:
@@ -96,14 +150,14 @@ done once). With the emulator running type:
(where obviously ../../MyTests/pdf_reference17.pdf is altered for your
machine). (adb lives in <sdk>/platform-tools if it's not on your path).
-13) With the emulator running (see step 11), execute
+16) With the emulator running (see step 14), execute
- ant install
+ ant debug install
-('ant.bat install' on Windows) and that will copy MuPDF into the emulator
-where you can run it from the launchpad screen.
+('ant.bat debug install' on Windows) and that will copy MuPDF into the
+emulator where you can run it from the launchpad screen.
-14) To see debug messages from the emulator (including stdout/stderr from
+17) To see debug messages from the emulator (including stdout/stderr from
our app), execute:
adb logcat
diff --git a/android/build.properties b/android/build.properties
deleted file mode 100644
index edc7f230..00000000
--- a/android/build.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is used to override default values used by the Ant build system.
-#
-# This file must be checked in Version Control Systems, as it is
-# integral to the build system of your project.
-
-# This file is only used by the Ant script.
-
-# You can use this to override default values such as
-# 'source.dir' for the location of your java source folder and
-# 'out.dir' for the location of your output folder.
-
-# You can also use it define how the release builds are signed by declaring
-# the following properties:
-# 'key.store' for the location of your keystore and
-# 'key.alias' for the name of the key to use.
-# The password will be asked during the build when you use the 'release' target.
-
diff --git a/android/build.xml b/android/build.xml
index 3ba2015b..7cb2cdf8 100644
--- a/android/build.xml
+++ b/android/build.xml
@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="MuPDF" default="help">
-<!-- The local.properties file is created and updated by the 'android'
- tool.
- It contains the path to the SDK. It should *NOT* be checked into
- Version Control Systems. -->
- <property file="local.properties" />
-
- <!-- The build.properties file can be created by you and is never touched
- by the 'android' tool. This is the place to change some of the
- default property values used by the Ant rules.
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <loadproperties srcFile="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
@@ -17,6 +16,9 @@
out.dir
The name of the output directory. Default is 'bin'.
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
@@ -24,26 +26,25 @@
application and should be checked into Version Control Systems.
-->
- <property file="build.properties" />
+ <property file="ant.properties" />
- <!-- The default.properties file is created and updated by the 'android'
+ <!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
- <property file="default.properties" />
+ <loadproperties srcFile="project.properties" />
- <!-- Custom Android task to deal with the project target, and import the
- proper rules.
- This requires ant 1.6.0 or above. -->
- <path id="android.antlibs">
- <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
- <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
- <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
- </path>
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'"
+ unless="sdk.dir"
+ />
- <taskdef name="setup"
- classname="com.android.ant.SetupTask"
- classpathref="android.antlibs" />
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
@@ -53,32 +54,32 @@
<target name="-pre-compile">
</target>
- [This is typically used for code obfuscation.
- Compiled code location: ${out.classes.absolute.dir}
- If this is not done in place, override ${out.dex.input.absolute.dir}]
+ /* This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir} */
<target name="-post-compile">
</target>
-->
-
- <!-- Execute the Android Setup task that will setup some properties
- specific to the target, and import the build rules files.
-
- The rules file is imported from
- <SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml
+ <!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
- <setup> task.
+ <import> task.
- customize it to your needs.
- - Customize the whole script.
+ - Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
- into this file, *after* the <setup> task
- - disable the import of the rules by changing the setup task
- below to <setup import="false" />.
+ into this file, replacing the <import> task.
- customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
-->
- <setup />
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
</project>
diff --git a/android/default.properties b/android/default.properties
deleted file mode 100644
index 0b9250e0..00000000
--- a/android/default.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-8
diff --git a/android/jni/Core.mk b/android/jni/Core.mk
index 4c3e75b5..7f145c60 100644
--- a/android/jni/Core.mk
+++ b/android/jni/Core.mk
@@ -4,6 +4,8 @@ include $(CLEAR_VARS)
MY_ROOT := ../..
+LOCAL_CFLAGS += -DARCH_ARM -DARCH_THUMB
+
LOCAL_C_INCLUDES := \
../thirdparty/jbig2dec \
../thirdparty/openjpeg-1.4/libopenjpeg \
@@ -53,7 +55,6 @@ LOCAL_SRC_FILES := \
$(MY_ROOT)/fitz/stm_buffer.c \
$(MY_ROOT)/fitz/stm_open.c \
$(MY_ROOT)/fitz/stm_read.c \
- $(MY_ROOT)/draw/arch_arm.c \
$(MY_ROOT)/draw/arch_port.c \
$(MY_ROOT)/draw/draw_affine.c \
$(MY_ROOT)/draw/draw_blend.c \
diff --git a/android/jni/mupdf.c b/android/jni/mupdf.c
index 463899af..a3d45d8d 100644
--- a/android/jni/mupdf.c
+++ b/android/jni/mupdf.c
@@ -17,6 +17,9 @@
/* Set to 1 to enable debug log traces. */
#define DEBUG 0
+/* Enable to log rendering times (render each frame 100 times and time) */
+#undef TIME_DISPLAY_LIST
+
/* Globals */
fz_colorspace *colorspace;
fz_glyph_cache *glyphcache;
@@ -190,7 +193,22 @@ Java_com_artifex_mupdf_MuPDFCore_drawPage(JNIEnv *env, jobject thiz, jobject bit
ctm = fz_concat(ctm, fz_scale(xscale, yscale));
bbox = fz_round_rect(fz_transform_rect(ctm,currentMediabox));
dev = fz_new_draw_device(glyphcache, pix);
+#ifdef TIME_DISPLAY_LIST
+ {
+ clock_t time;
+ int i;
+
+ LOGE("Executing display list");
+ time = clock();
+ for (i=0; i<100;i++) {
+#endif
fz_execute_display_list(currentPageList, dev, ctm, bbox);
+#ifdef TIME_DISPLAY_LIST
+ }
+ time = clock() - time;
+ LOGE("100 renders in %d (%d per sec)", time, CLOCKS_PER_SEC);
+ }
+#endif
fz_free_device(dev);
fz_drop_pixmap(pix);
LOGE("Rendered");
diff --git a/android/local.properties b/android/local.properties
index d0fd99a9..d0e1f0e6 100644
--- a/android/local.properties
+++ b/android/local.properties
@@ -1,2 +1,2 @@
#sdk.dir=/Library/android-sdk-mac_x86
-sdk.dir=C:\\Program Files\\android-sdk-windows
+sdk.dir=C:\\Program Files (x86)\\Android\\android-sdk
diff --git a/draw/draw_scale.c b/draw/draw_scale.c
index 427512ce..bb766398 100644
--- a/draw/draw_scale.c
+++ b/draw/draw_scale.c
@@ -16,6 +16,21 @@ and then positioning it at (frac(x),frac(y)).
*/
#define SINGLE_PIXEL_SPECIALS
+/* If we're compiling as thumb code, then we need to tell the compiler
+ * to enter and exit ARM mode around our assembly sections. If we move
+ * the ARM functions to a separate file and arrange for it to be compiled
+ * without thumb mode, we can save some time on entry.
+ */
+#ifdef ARCH_ARM
+#ifdef ARCH_THUMB
+#define ENTER_ARM ".balign 4\nmov r12,pc\nbx r12\n0:.arm\n"
+#define ENTER_THUMB "9:.thumb\n"
+#else
+#define ENTER_ARM
+#define ENTER_THUMB
+#endif
+#endif
+
#ifdef DEBUG_SCALING
#ifdef WIN32
#include <windows.h>
@@ -247,10 +262,10 @@ typedef struct fz_weights_s fz_weights;
struct fz_weights_s
{
+ int flip;
int count;
int max_len;
int n;
- int flip;
int new_line;
int index[1];
};
@@ -584,6 +599,274 @@ scale_row_to_temp(int *dst, unsigned char *src, fz_weights *weights)
}
}
+#ifdef ARCH_ARM
+
+static void
+scale_row_to_temp1(int *dst, unsigned char *src, fz_weights *weights)
+__attribute__((naked));
+
+static void
+scale_row_to_temp2(int *dst, unsigned char *src, fz_weights *weights)
+__attribute__((naked));
+
+static void
+scale_row_to_temp4(int *dst, unsigned char *src, fz_weights *weights)
+__attribute__((naked));
+
+static void
+scale_row_from_temp(unsigned char *dst, int *src, fz_weights *weights, int width, int row)
+__attribute__((naked));
+
+static void
+scale_row_to_temp1(int *dst, unsigned char *src, fz_weights *weights)
+{
+ /* possible optimisation in here; unroll inner loops to avoid stall. */
+ asm volatile(
+ ENTER_ARM
+ "stmfd r13!,{r4-r5,r9,r14} \n"
+ "@ r0 = dst \n"
+ "@ r1 = src \n"
+ "@ r2 = weights \n"
+ "ldr r12,[r2],#4 @ r12= flip \n"
+ "ldr r3, [r2],#16 @ r3 = count r2 = &index\n"
+ "ldr r4, [r2] @ r4 = index[0] \n"
+ "cmp r12,#0 @ if (flip) \n"
+ "beq 4f @ { \n"
+ "add r2, r2, r4, LSL #2 @ r2 = &index[index[0]] \n"
+ "add r0, r0, r3, LSL #2 @ dst += count \n"
+ "1: \n"
+ "ldr r4, [r2], #4 @ r4 = *contrib++ \n"
+ "ldr r9, [r2], #4 @ r9 = len = *contrib++ \n"
+ "mov r5, #0 @ r5 = a = 0 \n"
+ "add r4, r1, r4 @ r4 = min = &src[r4] \n"
+ "cmp r9, #0 @ while (len-- > 0) \n"
+ "beq 3f @ { \n"
+ "2: \n"
+ "ldr r12,[r2], #4 @ r12 = *contrib++ \n"
+ "ldrb r14,[r4], #1 @ r14 = *min++ \n"
+ "subs r9, r9, #1 @ r9 = len-- \n"
+ "@stall on r14 \n"
+ "mla r5, r12,r14,r5 @ g += r14 * r12 \n"
+ "bgt 2b @ } \n"
+ "3: \n"
+ "str r5,[r0, #-4]! @ *--dst=a \n"
+ "subs r3, r3, #1 @ i-- \n"
+ "bgt 1b @ \n"
+ "ldmfd r13!,{r4-r5,r9,PC} @ pop, return to thumb \n"
+ "4:"
+ "add r2, r2, r4, LSL #2 @ r2 = &index[index[0]] \n"
+ "5:"
+ "ldr r4, [r2], #4 @ r4 = *contrib++ \n"
+ "ldr r9, [r2], #4 @ r9 = len = *contrib++ \n"
+ "mov r5, #0 @ r5 = a = 0 \n"
+ "add r4, r1, r4 @ r4 = min = &src[r4] \n"
+ "cmp r9, #0 @ while (len-- > 0) \n"
+ "beq 7f @ { \n"
+ "6: \n"
+ "ldr r12,[r2], #4 @ r12 = *contrib++ \n"
+ "ldrb r14,[r4], #1 @ r14 = *min++ \n"
+ "subs r9, r9, #1 @ r9 = len-- \n"
+ "@stall on r14 \n"
+ "mla r5, r12,r14,r5 @ a += r14 * r12 \n"
+ "bgt 6b @ } \n"
+ "7: \n"
+ "str r5, [r0], #4 @ *dst++=a \n"
+ "subs r3, r3, #1 @ i-- \n"
+ "bgt 5b @ \n"
+ "ldmfd r13!,{r4-r5,r9,PC} @ pop, return to thumb \n"
+ ENTER_THUMB
+ );
+}
+
+static void
+scale_row_to_temp2(int *dst, unsigned char *src, fz_weights *weights)
+{
+ asm volatile(
+ ENTER_ARM
+ "stmfd r13!,{r4-r6,r9-r11,r14} \n"
+ "@ r0 = dst \n"
+ "@ r1 = src \n"
+ "@ r2 = weights \n"
+ "ldr r12,[r2],#4 @ r12= flip \n"
+ "ldr r3, [r2],#16 @ r3 = count r2 = &index\n"
+ "ldr r4, [r2] @ r4 = index[0] \n"
+ "cmp r12,#0 @ if (flip) \n"
+ "beq 4f @ { \n"
+ "add r2, r2, r4, LSL #2 @ r2 = &index[index[0]] \n"
+ "add r0, r0, r3, LSL #3 @ dst += 2*count \n"
+ "1: \n"
+ "ldr r4, [r2], #4 @ r4 = *contrib++ \n"
+ "ldr r9, [r2], #4 @ r9 = len = *contrib++ \n"
+ "mov r5, #0 @ r5 = g = 0 \n"
+ "mov r6, #0 @ r6 = a = 0 \n"
+ "add r4, r1, r4, LSL #1 @ r4 = min = &src[2*r4] \n"
+ "cmp r9, #0 @ while (len-- > 0) \n"
+ "beq 3f @ { \n"
+ "2: \n"
+ "ldr r14,[r2], #4 @ r14 = *contrib++ \n"
+ "ldrb r11,[r4], #1 @ r11 = *min++ \n"
+ "ldrb r12,[r4], #1 @ r12 = *min++ \n"
+ "subs r9, r9, #1 @ r9 = len-- \n"
+ "mla r5, r14,r11,r5 @ g += r11 * r14 \n"
+ "mla r6, r14,r12,r6 @ a += r12 * r14 \n"
+ "bgt 2b @ } \n"
+ "3: \n"
+ "stmdb r0!,{r5,r6} @ *--dst=a;*--dst=g; \n"
+ "subs r3, r3, #1 @ i-- \n"
+ "bgt 1b @ \n"
+ "ldmfd r13!,{r4-r6,r9-r11,PC} @ pop, return to thumb \n"
+ "4:"
+ "add r2, r2, r4, LSL #2 @ r2 = &index[index[0]] \n"
+ "5:"
+ "ldr r4, [r2], #4 @ r4 = *contrib++ \n"
+ "ldr r9, [r2], #4 @ r9 = len = *contrib++ \n"
+ "mov r5, #0 @ r5 = g = 0 \n"
+ "mov r6, #0 @ r6 = a = 0 \n"
+ "add r4, r1, r4, LSL #1 @ r4 = min = &src[2*r4] \n"
+ "cmp r9, #0 @ while (len-- > 0) \n"
+ "beq 7f @ { \n"
+ "6: \n"
+ "ldr r14,[r2], #4 @ r10 = *contrib++ \n"
+ "ldrb r11,[r4], #1 @ r11 = *min++ \n"
+ "ldrb r12,[r4], #1 @ r12 = *min++ \n"
+ "subs r9, r9, #1 @ r9 = len-- \n"
+ "mla r5, r14,r11,r5 @ g += r11 * r14 \n"
+ "mla r6, r14,r12,r6 @ a += r12 * r14 \n"
+ "bgt 6b @ } \n"
+ "7: \n"
+ "stmia r0!,{r5,r6} @ *dst++=r;*dst++=g; \n"
+ "subs r3, r3, #1 @ i-- \n"
+ "bgt 5b @ \n"
+ "ldmfd r13!,{r4-r6,r9-r11,PC} @ pop, return to thumb \n"
+ ENTER_THUMB
+ );
+}
+
+static void
+scale_row_to_temp4(int *dst, unsigned char *src, fz_weights *weights)
+{
+ asm volatile(
+ ENTER_ARM
+ "stmfd r13!,{r4-r11,r14} \n"
+ "@ r0 = dst \n"
+ "@ r1 = src \n"
+ "@ r2 = weights \n"
+ "ldr r12,[r2],#4 @ r12= flip \n"
+ "ldr r3, [r2],#16 @ r3 = count r2 = &index\n"
+ "ldr r4, [r2] @ r4 = index[0] \n"
+ "cmp r12,#0 @ if (flip) \n"
+ "beq 4f @ { \n"
+ "add r2, r2, r4, LSL #2 @ r2 = &index[index[0]] \n"
+ "add r0, r0, r3, LSL #4 @ dst += 4*count \n"
+ "1: \n"
+ "ldr r4, [r2], #4 @ r4 = *contrib++ \n"
+ "ldr r9, [r2], #4 @ r9 = len = *contrib++ \n"
+ "mov r5, #0 @ r5 = r = 0 \n"
+ "mov r6, #0 @ r6 = g = 0 \n"
+ "mov r7, #0 @ r7 = b = 0 \n"
+ "mov r8, #0 @ r8 = a = 0 \n"
+ "add r4, r1, r4, LSL #2 @ r4 = min = &src[4*r4] \n"
+ "cmp r9, #0 @ while (len-- > 0) \n"
+ "beq 3f @ { \n"
+ "2: \n"
+ "ldr r10,[r2], #4 @ r10 = *contrib++ \n"
+ "ldrb r11,[r4], #1 @ r11 = *min++ \n"
+ "ldrb r12,[r4], #1 @ r12 = *min++ \n"
+ "ldrb r14,[r4], #1 @ r14 = *min++ \n"
+ "mla r5, r10,r11,r5 @ r += r11 * r10 \n"
+ "ldrb r11,[r4], #1 @ r11 = *min++ \n"
+ "mla r6, r10,r12,r6 @ g += r12 * r10 \n"
+ "mla r7, r10,r14,r7 @ b += r14 * r10 \n"
+ "mla r8, r10,r11,r8 @ a += r11 * r10 \n"
+ "subs r9, r9, #1 @ r9 = len-- \n"
+ "bgt 2b @ } \n"
+ "3: \n"
+ "stmdb r0!,{r5,r6,r7,r8} @ *--dst=a;*--dst=b; \n"
+ " @ *--dst=g;*--dst=r; \n"
+ "subs r3, r3, #1 @ i-- \n"
+ "bgt 1b @ \n"
+ "ldmfd r13!,{r4-r11,PC} @ pop, return to thumb \n"
+ "4:"
+ "add r2, r2, r4, LSL #2 @ r2 = &index[index[0]] \n"
+ "5:"
+ "ldr r4, [r2], #4 @ r4 = *contrib++ \n"
+ "ldr r9, [r2], #4 @ r9 = len = *contrib++ \n"
+ "mov r5, #0 @ r5 = r = 0 \n"
+ "mov r6, #0 @ r6 = g = 0 \n"
+ "mov r7, #0 @ r7 = b = 0 \n"
+ "mov r8, #0 @ r8 = a = 0 \n"
+ "add r4, r1, r4, LSL #2 @ r4 = min = &src[4*r4] \n"
+ "cmp r9, #0 @ while (len-- > 0) \n"
+ "beq 7f @ { \n"
+ "6: \n"
+ "ldr r10,[r2], #4 @ r10 = *contrib++ \n"
+ "ldrb r11,[r4], #1 @ r11 = *min++ \n"
+ "ldrb r12,[r4], #1 @ r12 = *min++ \n"
+ "ldrb r14,[r4], #1 @ r14 = *min++ \n"
+ "mla r5, r10,r11,r5 @ r += r11 * r10 \n"
+ "ldrb r11,[r4], #1 @ r11 = *min++ \n"
+ "mla r6, r10,r12,r6 @ g += r12 * r10 \n"
+ "mla r7, r10,r14,r7 @ b += r14 * r10 \n"
+ "mla r8, r10,r11,r8 @ a += r11 * r10 \n"
+ "subs r9, r9, #1 @ r9 = len-- \n"
+ "bgt 6b @ } \n"
+ "7: \n"
+ "stmia r0!,{r5,r6,r7,r8} @ *dst++=r;*dst++=g; \n"
+ " @ *dst++=b;*dst++=a; \n"
+ "subs r3, r3, #1 @ i-- \n"
+ "bgt 5b @ \n"
+ "ldmfd r13!,{r4-r11,PC} @ pop, return to thumb \n"
+ ENTER_THUMB
+ );
+}
+
+static void
+scale_row_from_temp(unsigned char *dst, int *src, fz_weights *weights, int width, int row)
+{
+ asm volatile(
+ ENTER_ARM
+ "ldr r12,[r13] @ r12= row \n"
+ "add r2, r2, #20 @ r2 = weights->index \n"
+ "stmfd r13!,{r4-r11,r14} \n"
+ "@ r0 = dst \n"
+ "@ r1 = src \n"
+ "@ r2 = &weights->index[0] \n"
+ "@ r3 = width \n"
+ "@ r12= row \n"
+ "ldr r4, [r2, r12, LSL #2] @ r4 = index[row] \n"
+ "add r2, r2, #4 @ r2 = &index[1] \n"
+ "mov r6, r3 @ r6 = x = width \n"
+ "ldr r14,[r2, r4, LSL #2]! @ r2 = contrib = index[index[row]+1]\n"
+ " @ r14= len = *contrib \n"
+ "1: \n"
+ "mov r5, r1 @ r5 = min = src \n"
+ "mov r7, #1<<15 @ r7 = val = 1<<15 \n"
+ "movs r8, r14 @ r8 = len2 = len \n"
+ "add r9, r2, #4 @ r9 = contrib2 \n"
+ "ble 3f @ while (len2-- > 0) { \n"
+ "2: \n"
+ "ldr r10,[r9], #4 @ r10 = *contrib2++ \n"
+ "ldr r12,[r5], r3, LSL #2 @ r12 = *min r5 = min += width\n"
+ "subs r8, r8, #1 @ len2-- \n"
+ "@ stall r12 \n"
+ "mla r7, r10,r12,r7 @ val += r12 * r10 \n"
+ "bgt 2b @ } \n"
+ "3: \n"
+ "movs r7, r7, asr #16 @ r7 = val >>= 16 \n"
+ "movlt r7, #0 @ if (r7 < 0) r7 = 0 \n"
+ "cmp r7, #255 @ if (r7 > 255) \n"
+ "add r1, r1, #4 @ src++ \n"
+ "movgt r7, #255 @ r7 = 255 \n"
+ "subs r6, r6, #1 @ x-- \n"
+ "strb r7, [r0], #1 @ *dst++ = val \n"
+ "bgt 1b @ \n"
+ "ldmfd r13!,{r4-r11,PC} @ pop, return to thumb \n"
+ ENTER_THUMB
+ );
+}
+
+#else
+
static void
scale_row_to_temp1(int *dst, unsigned char *src, fz_weights *weights)
{
@@ -672,54 +955,13 @@ static void
scale_row_to_temp4(int *dst, unsigned char *src, fz_weights *weights)
{
int *contrib = &weights->index[weights->index[0]];
-#ifndef ARCH_ARM
int len, i;
unsigned char *min;
-#endif
assert(weights->n == 4);
if (weights->flip)
{
dst += 4*weights->count;
-#ifdef ARCH_ARM
- asm volatile(
- "1:"
- "ldr r4, [%2], #4 @ r4 = *contrib++ \n"
- "ldr r9, [%2], #4 @ r9 = len = *contrib++ \n"
- "mov r5, #0 @ r5 = r = 0 \n"
- "mov r6, #0 @ r6 = g = 0 \n"
- "mov r7, #0 @ r7 = b = 0 \n"
- "mov r8, #0 @ r8 = a = 0 \n"
- "add r4, %1, r4, LSL #2 @ r4 = min = &src[4*r4] \n"
- "cmp r9, #0 @ while (len-- > 0) \n"
- "beq 3f @ { \n"
- "2: \n"
- "ldr r10,[%2], #4 @ r10 = *contrib++ \n"
- "ldrb r11,[r4], #1 @ r11 = *min++ \n"
- "ldrb r12,[r4], #1 @ r12 = *min++ \n"
- "ldrb r14,[r4], #1 @ r14 = *min++ \n"
- "mla r5, r10,r11,r5 @ r += r11 * r10 \n"
- "ldrb r11,[r4], #1 @ r11 = *min++ \n"
- "mla r6, r10,r12,r6 @ g += r12 * r10 \n"
- "mla r7, r10,r14,r7 @ b += r14 * r10 \n"
- "mla r8, r10,r11,r8 @ a += r11 * r10 \n"
- "subs r9, r9, #1 @ r9 = len-- \n"
- "bgt 2b @ } \n"
- "stmdb %0!,{r5,r6,r7,r8} @ *--dst=a;*--dst=b; \n"
- "3: @ *--dst=g;*--dst=r; \n"
- "subs %3, %3, #1 @ i-- \n"
- "bgt 1b @ \n"
- :
- :
- "r" (dst),
- "r" (src),
- "r" (contrib),
- "r" (weights->count)
- :
- "r4","r5","r6","r7","r8","r9","r10","r11","r12","r14",
- "memory","cc"
- );
-#else
for (i=weights->count; i > 0; i--)
{
int r = 0;
@@ -740,49 +982,9 @@ scale_row_to_temp4(int *dst, unsigned char *src, fz_weights *weights)
*--dst = g;
*--dst = r;
}
-#endif
}
else
{
-#ifdef ARCH_ARM
- asm volatile(
- "1:"
- "ldr r4, [%2], #4 @ r4 = *contrib++ \n"
- "ldr r9, [%2], #4 @ r9 = len = *contrib++ \n"
- "mov r5, #0 @ r5 = r = 0 \n"
- "mov r6, #0 @ r6 = g = 0 \n"
- "mov r7, #0 @ r7 = b = 0 \n"
- "mov r8, #0 @ r8 = a = 0 \n"
- "add r4, %1, r4, LSL #2 @ r4 = min = &src[4*r4] \n"
- "cmp r9, #0 @ while (len-- > 0) \n"
- "beq 3f @ { \n"
- "2: \n"
- "ldr r10,[%2], #4 @ r10 = *contrib++ \n"
- "ldrb r11,[r4], #1 @ r11 = *min++ \n"
- "ldrb r12,[r4], #1 @ r12 = *min++ \n"
- "ldrb r14,[r4], #1 @ r14 = *min++ \n"
- "mla r5, r10,r11,r5 @ r += r11 * r10 \n"
- "ldrb r11,[r4], #1 @ r11 = *min++ \n"
- "mla r6, r10,r12,r6 @ g += r12 * r10 \n"
- "mla r7, r10,r14,r7 @ b += r14 * r10 \n"
- "mla r8, r10,r11,r8 @ a += r11 * r10 \n"
- "subs r9, r9, #1 @ r9 = len-- \n"
- "bgt 2b @ } \n"
- "stmia %0!,{r5,r6,r7,r8} @ *dst++=r;*dst++=g; \n"
- "3: @ *dst++=b;*dst++=a; \n"
- "subs %3, %3, #1 @ i-- \n"
- "bgt 1b @ \n"
- :
- :
- "r" (dst),
- "r" (src),
- "r" (contrib),
- "r" (weights->count)
- :
- "r4","r5","r6","r7","r8","r9","r10","r11","r12","r14",
- "memory","cc"
- );
-#else
for (i=weights->count; i > 0; i--)
{
int r = 0;
@@ -803,7 +1005,6 @@ scale_row_to_temp4(int *dst, unsigned char *src, fz_weights *weights)
*dst++ = b;
*dst++ = a;
}
-#endif
}
}
@@ -836,6 +1037,7 @@ scale_row_from_temp(unsigned char *dst, int *src, fz_weights *weights, int width
src++;
}
}
+#endif
#ifdef SINGLE_PIXEL_SPECIALS
static void