summaryrefslogtreecommitdiff
path: root/source/fitz/draw-scale-simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/draw-scale-simple.c')
-rw-r--r--source/fitz/draw-scale-simple.c149
1 files changed, 147 insertions, 2 deletions
diff --git a/source/fitz/draw-scale-simple.c b/source/fitz/draw-scale-simple.c
index 0f267743..5d4c5b98 100644
--- a/source/fitz/draw-scale-simple.c
+++ b/source/fitz/draw-scale-simple.c
@@ -560,6 +560,10 @@ scale_row_to_temp2(unsigned char *dst, unsigned char *src, fz_weights *weights)
__attribute__((naked));
static void
+scale_row_to_temp3(unsigned char *dst, unsigned char *src, fz_weights *weights)
+__attribute__((naked));
+
+static void
scale_row_to_temp4(unsigned char *dst, unsigned char *src, fz_weights *weights)
__attribute__((naked));
@@ -704,6 +708,91 @@ scale_row_to_temp2(unsigned char *dst, unsigned char *src, fz_weights *weights)
}
static void
+scale_row_to_temp3(unsigned char *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],#20 @ 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 #1 @ \n"
+ "add r2, r2, r4 @ r2 = &index[index[0]] \n"
+ "add r0, r0, r3, LSL #1 @ \n"
+ "add r0, r0, r3 @ dst += 3*count \n"
+ "1: \n"
+ "ldr r4, [r2], #4 @ r4 = *contrib++ \n"
+ "ldr r9, [r2], #4 @ r9 = len = *contrib++ \n"
+ "mov r5, #128 @ r5 = r = 128 \n"
+ "mov r6, #128 @ r6 = g = 128 \n"
+ "add r7, r1, r4, LSL #1 @ \n"
+ "add r4, r7, r4 @ r4 = min = &src[3*r4] \n"
+ "mov r7, #128 @ r7 = b = 128 \n"
+ "cmp r9, #0 @ while (len-- > 0) \n"
+ "beq 3f @ { \n"
+ "2: \n"
+ "ldr r14,[r2], #4 @ r14 = *contrib++ \n"
+ "ldrb r8, [r4], #1 @ r8 = *min++ \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,r8, r5 @ r += r8 * r14 \n"
+ "mla r6, r14,r11,r6 @ g += r11 * r14 \n"
+ "mla r7, r14,r12,r7 @ b += r12 * r14 \n"
+ "bgt 2b @ } \n"
+ "3: \n"
+ "mov r5, r5, lsr #8 @ r >>= 8 \n"
+ "mov r6, r6, lsr #8 @ g >>= 8 \n"
+ "mov r7, r7, lsr #8 @ b >>= 8 \n"
+ "strb r5, [r0, #-3]! @ *--dst=r \n"
+ "strb r6, [r0, #1] @ *--dst=g \n"
+ "strb r7, [r0, #2] @ *--dst=b \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 #1 @ \n"
+ "add r2, r2, r4 @ r2 = &index[index[0]] \n"
+ "5:"
+ "ldr r4, [r2], #4 @ r4 = *contrib++ \n"
+ "ldr r9, [r2], #4 @ r9 = len = *contrib++ \n"
+ "mov r5, #128 @ r5 = r = 128 \n"
+ "mov r6, #128 @ r6 = g = 128 \n"
+ "add r7, r1, r4, LSL #1 @ r7 = min = &src[2*r4] \n"
+ "add r4, r7, r4 @ r4 = min = &src[3*r4] \n"
+ "mov r7, #128 @ r7 = b = 128 \n"
+ "cmp r9, #0 @ while (len-- > 0) \n"
+ "beq 7f @ { \n"
+ "6: \n"
+ "ldr r14,[r2], #4 @ r10 = *contrib++ \n"
+ "ldrb r8, [r4], #1 @ r8 = *min++ \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,r8, r5 @ r += r8 * r14 \n"
+ "mla r6, r14,r11,r6 @ g += r11 * r14 \n"
+ "mla r7, r14,r12,r7 @ b += r12 * r14 \n"
+ "bgt 6b @ } \n"
+ "7: \n"
+ "mov r5, r5, lsr #8 @ r >>= 8 \n"
+ "mov r6, r6, lsr #8 @ g >>= 8 \n"
+ "mov r7, r7, lsr #8 @ b >>= 8 \n"
+ "strb r5, [r0], #1 @ *dst++=r \n"
+ "strb r6, [r0], #1 @ *dst++=g \n"
+ "strb r7, [r0], #1 @ *dst++=b \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_to_temp4(unsigned char *dst, unsigned char *src, fz_weights *weights)
{
asm volatile(
@@ -943,6 +1032,59 @@ scale_row_to_temp2(unsigned char *dst, unsigned char *src, fz_weights *weights)
}
static void
+scale_row_to_temp3(unsigned char *dst, unsigned char *src, fz_weights *weights)
+{
+ int *contrib = &weights->index[weights->index[0]];
+ int len, i;
+ unsigned char *min;
+
+ assert(weights->n == 3);
+ if (weights->flip)
+ {
+ dst += 3*weights->count;
+ for (i=weights->count; i > 0; i--)
+ {
+ int c1 = 128;
+ int c2 = 128;
+ int c3 = 128;
+ min = &src[3 * *contrib++];
+ len = *contrib++;
+ while (len-- > 0)
+ {
+ int c = *contrib++;
+ c1 += *min++ * c;
+ c2 += *min++ * c;
+ c3 += *min++ * c;
+ }
+ *--dst = (unsigned char)(c3>>8);
+ *--dst = (unsigned char)(c2>>8);
+ *--dst = (unsigned char)(c1>>8);
+ }
+ }
+ else
+ {
+ for (i=weights->count; i > 0; i--)
+ {
+ int c1 = 128;
+ int c2 = 128;
+ int c3 = 128;
+ min = &src[3 * *contrib++];
+ len = *contrib++;
+ while (len-- > 0)
+ {
+ int c = *contrib++;
+ c1 += *min++ * c;
+ c2 += *min++ * c;
+ c3 += *min++ * c;
+ }
+ *dst++ = (unsigned char)(c1>>8);
+ *dst++ = (unsigned char)(c2>>8);
+ *dst++ = (unsigned char)(c3>>8);
+ }
+ }
+}
+
+static void
scale_row_to_temp4(unsigned char *dst, unsigned char *src, fz_weights *weights)
{
int *contrib = &weights->index[weights->index[0]];
@@ -1429,13 +1571,16 @@ fz_scale_pixmap_cached(fz_context *ctx, const fz_pixmap *src, float x, float y,
default:
row_scale = scale_row_to_temp;
break;
- case 1: /* Image mask case */
+ case 1: /* Image mask case or Greyscale case */
row_scale = scale_row_to_temp1;
break;
case 2: /* Greyscale with alpha case */
row_scale = scale_row_to_temp2;
break;
- case 4: /* RGBA */
+ case 3: /* RGB case */
+ row_scale = scale_row_to_temp3;
+ break;
+ case 4: /* RGBA or CMYK case */
row_scale = scale_row_to_temp4;
break;
}