1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 7d48be6..100b874 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -151,3 +151,4 @@ superdom.c
 #endif /* m:robe 500 */

 md5sum.c
+test_greylib_bitmap_scale.c
diff --git a/apps/recorder/resize.c b/apps/recorder/resize.c
index 99ccc84..d81e980 100644
--- a/apps/recorder/resize.c
+++ b/apps/recorder/resize.c
@@ -59,30 +59,44 @@
 #define DEBUGF(...)
 #endif

+#define ALIGN_BUF(ptr,len,align) \
+{\
+    uintptr_t tmp_ptr1 = (uintptr_t)ptr; \
+    uintptr_t tmp_ptr2 = ALIGN_UP(tmp_ptr1,align);\
+    len -= tmp_ptr2 - tmp_ptr1;\
+    ptr = (typeof(ptr))tmp_ptr2;\
+}
+
 /* calculate the maximum dimensions which will preserve the aspect ration of
    src while fitting in the constraints passed in dst, and store result in dst,
    returning 0 if rounding and 1 if not rounding.
 */
 int recalc_dimension(struct dim *dst, struct dim *src)
 {
+    /* This only looks backwards. The input image size is being pre-scaled by
+     * the inverse of the pixel aspect ratio, so that once the size it scaled
+     * to meet the output constraints, the scaled image will have appropriate
+     * proportions.
+     */
+    int sw = src->width * LCD_PIXEL_ASPECT_HEIGHT;
+    int sh = src->height * LCD_PIXEL_ASPECT_WIDTH;
     int tmp;
     if (dst->width <= 0)
         dst->width = LCD_WIDTH;
     if (dst->height <= 0)
         dst->height = LCD_HEIGHT;
 #ifndef HAVE_UPSCALER
-    if (dst->width > src->width || dst->height > src->height)
+    if (dst->width > sw || dst->height > sh)
     {
-        dst->width = src->width;
-        dst->height = src->height;
+        dst->width = sw;
+        dst->height = sh;
     }
-    if (src->width == dst->width && src->height == dst->height)
+    if (sw == dst->width && sh == dst->height)
         return 1;
 #endif
-    tmp = (src->width * dst->height + (src->height >> 1)) / src->height;
+    tmp = (sw * dst->height + (sh >> 1)) / sh;
     if (tmp > dst->width)
-        dst->height = (src->height * dst->width + (src->width >> 1))
-                      / src->width;
+        dst->height = (sh * dst->width + (sw >> 1)) / sw;
     else
         dst->width = tmp;
     return src->width == dst->width && src->height == dst->height;
@@ -616,10 +630,7 @@ int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
     uint8_t sc_buf[(needed <= len  || needed > MAX_SC_STACK_ALLOC) ?
                    0 : needed];
 #endif
-#if CONFIG_CODEC == SWCODEC
-    len = (unsigned int)align_buffer(PUN_PTR(void**, &buf), len,
-                                         sizeof(uint32_t));
-#endif
+    ALIGN_BUF(buf, len, 4);
     if (needed > len)
     {
 #if MAX_SC_STACK_ALLOC
diff --git a/firmware/export/config-fmrecorder.h b/firmware/export/config-fmrecorder.h
index 50cee2b..da281bd 100644
--- a/firmware/export/config-fmrecorder.h
+++ b/firmware/export/config-fmrecorder.h
@@ -34,6 +34,9 @@
 #define LCD_HEIGHT 64
 #define LCD_DEPTH  1

+#define LCD_PIXEL_ASPECT_WIDTH 4
+#define LCD_PIXEL_ASPECT_HEIGHT 5
+
 #define LCD_PIXELFORMAT VERTICAL_PACKING

 /* define this if you have a Recorder style 10-key keyboard */
diff --git a/firmware/export/config-ondiofm.h b/firmware/export/config-ondiofm.h
index 8233728..1b3b266 100644
--- a/firmware/export/config-ondiofm.h
+++ b/firmware/export/config-ondiofm.h
@@ -24,6 +24,9 @@
 #define LCD_HEIGHT 64
 #define LCD_DEPTH  1

+#define LCD_PIXEL_ASPECT_WIDTH 4
+#define LCD_PIXEL_ASPECT_HEIGHT 5
+
 #define LCD_PIXELFORMAT VERTICAL_PACKING

 /* define this if you have an Ondio style 6-key keyboard */
diff --git a/firmware/export/config-ondiosp.h b/firmware/export/config-ondiosp.h
index 5fb7806..85065f4 100644
--- a/firmware/export/config-ondiosp.h
+++ b/firmware/export/config-ondiosp.h
@@ -17,6 +17,9 @@
 #define LCD_HEIGHT 64
 #define LCD_DEPTH  1

+#define LCD_PIXEL_ASPECT_WIDTH 4
+#define LCD_PIXEL_ASPECT_HEIGHT 5
+
 #define LCD_PIXELFORMAT VERTICAL_PACKING

 /* define this if you have an Ondio style 6-key keyboard */
diff --git a/firmware/export/config-recorder.h b/firmware/export/config-recorder.h
index 75aa2cf..ff74eef 100644
--- a/firmware/export/config-recorder.h
+++ b/firmware/export/config-recorder.h
@@ -34,6 +34,9 @@
 #define LCD_HEIGHT 64
 #define LCD_DEPTH  1

+#define LCD_PIXEL_ASPECT_WIDTH 4
+#define LCD_PIXEL_ASPECT_HEIGHT 5
+
 #define LCD_PIXELFORMAT VERTICAL_PACKING

 /* define this if you have the Recorder's 10-key keyboard */
diff --git a/firmware/export/config-recorderv2.h b/firmware/export/config-recorderv2.h
index 3244f19..4e77e3d 100644
--- a/firmware/export/config-recorderv2.h
+++ b/firmware/export/config-recorderv2.h
@@ -34,6 +34,9 @@
 #define LCD_HEIGHT 64
 #define LCD_DEPTH  1

+#define LCD_PIXEL_ASPECT_WIDTH 4
+#define LCD_PIXEL_ASPECT_HEIGHT 5
+
 #define LCD_PIXELFORMAT VERTICAL_PACKING

 /* define this if you have a Recorder style 10-key keyboard */
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 9bc6c7c..15b1375 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -379,6 +379,16 @@
 #endif
 #endif

+/* Pixel aspect ratio is defined in terms of a multiplier for pixel width and
+ * height, and is set to 1:1 if the target does not set a value
+ */
+#ifndef LCD_PIXEL_ASPECT_HEIGHT
+#define LCD_PIXEL_ASPECT_HEIGHT 1
+#endif
+#ifndef LCD_PIXEL_ASPECT_WIDTH
+#define LCD_PIXEL_ASPECT_WIDTH 1
+#endif
+
 /* define this in the target config.h to use a different size */
 #ifndef CONFIG_DEFAULT_ICON_HEIGHT
 #define CONFIG_DEFAULT_ICON_HEIGHT 8