summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-11-08 21:39:23 +0000
committerThomas Martitz <kugel@rockbox.org>2011-11-08 21:39:23 +0000
commitc7b8054714cff4580ddbdbf5c9d503b20ff45740 (patch)
tree20e896da7940e667e5696a7dafaffebd337783df
parentf443e7bbf7771ce3a79b1c2116b9cf216f15938f (diff)
downloadrockbox-c7b8054714cff4580ddbdbf5c9d503b20ff45740.tar.gz
rockbox-c7b8054714cff4580ddbdbf5c9d503b20ff45740.zip
Adapt the resize-on-load image scalers to support the alpha channel.
Now 32bit BMPs with alpha channel can be up- and downscaled without losing transparency information. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30938 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/recorder/resize.c122
-rw-r--r--apps/recorder/resize.h3
2 files changed, 66 insertions, 59 deletions
diff --git a/apps/recorder/resize.c b/apps/recorder/resize.c
index b570116179..a68a5f2e9f 100644
--- a/apps/recorder/resize.c
+++ b/apps/recorder/resize.c
@@ -70,6 +70,12 @@
70#define MULQ(a, b) ((a) * (b)) 70#define MULQ(a, b) ((a) * (b))
71#endif 71#endif
72 72
73#ifdef HAVE_LCD_COLOR
74#define CHANNEL_BYTES (sizeof(struct uint32_argb)/sizeof(uint32_t))
75#else
76#define CHANNEL_BYTES (sizeof(uint32_t)/sizeof(uint32_t)) /* packed */
77#endif
78
73/* calculate the maximum dimensions which will preserve the aspect ration of 79/* calculate the maximum dimensions which will preserve the aspect ration of
74 src while fitting in the constraints passed in dst, and store result in dst, 80 src while fitting in the constraints passed in dst, and store result in dst,
75 returning 0 if rounding and 1 if not rounding. 81 returning 0 if rounding and 1 if not rounding.
@@ -171,9 +177,9 @@ static bool scale_h_area(void *out_line_ptr,
171 h_o_val = ctx->h_o_val; 177 h_o_val = ctx->h_o_val;
172#endif 178#endif
173#ifdef HAVE_LCD_COLOR 179#ifdef HAVE_LCD_COLOR
174 struct uint32_rgb rgbvalacc = { 0, 0, 0 }, 180 struct uint32_argb rgbvalacc = { 0, 0, 0, 0 },
175 rgbvaltmp = { 0, 0, 0 }, 181 rgbvaltmp = { 0, 0, 0, 0 },
176 *out_line = (struct uint32_rgb *)out_line_ptr; 182 *out_line = (struct uint32_argb *)out_line_ptr;
177#else 183#else
178 uint32_t acc = 0, tmp = 0, *out_line = (uint32_t*)out_line_ptr; 184 uint32_t acc = 0, tmp = 0, *out_line = (uint32_t*)out_line_ptr;
179#endif 185#endif
@@ -204,53 +210,65 @@ static bool scale_h_area(void *out_line_ptr,
204 MAC(rgbvalacc.r, h_o_val, 0); 210 MAC(rgbvalacc.r, h_o_val, 0);
205 MAC(rgbvalacc.g, h_o_val, 1); 211 MAC(rgbvalacc.g, h_o_val, 1);
206 MAC(rgbvalacc.b, h_o_val, 2); 212 MAC(rgbvalacc.b, h_o_val, 2);
213 MAC(rgbvalacc.a, h_o_val, 3);
207 MAC(rgbvaltmp.r, mul, 0); 214 MAC(rgbvaltmp.r, mul, 0);
208 MAC(rgbvaltmp.g, mul, 1); 215 MAC(rgbvaltmp.g, mul, 1);
209 MAC(rgbvaltmp.b, mul, 2); 216 MAC(rgbvaltmp.b, mul, 2);
217 MAC(rgbvaltmp.a, mul, 3);
210 /* get new pixel , then add its partial coverage to this area */ 218 /* get new pixel , then add its partial coverage to this area */
211 mul = h_o_val - oxe; 219 mul = h_o_val - oxe;
212 rgbvaltmp.r = part->buf->red; 220 rgbvaltmp.r = part->buf->red;
213 rgbvaltmp.g = part->buf->green; 221 rgbvaltmp.g = part->buf->green;
214 rgbvaltmp.b = part->buf->blue; 222 rgbvaltmp.b = part->buf->blue;
223 rgbvaltmp.a = part->buf->alpha;
215 MAC(rgbvaltmp.r, mul, 0); 224 MAC(rgbvaltmp.r, mul, 0);
216 MAC(rgbvaltmp.g, mul, 1); 225 MAC(rgbvaltmp.g, mul, 1);
217 MAC(rgbvaltmp.b, mul, 2); 226 MAC(rgbvaltmp.b, mul, 2);
227 MAC(rgbvaltmp.a, mul, 3);
218 MAC_OUT(rgbvalacc.r, 0); 228 MAC_OUT(rgbvalacc.r, 0);
219 MAC_OUT(rgbvalacc.g, 1); 229 MAC_OUT(rgbvalacc.g, 1);
220 MAC_OUT(rgbvalacc.b, 2); 230 MAC_OUT(rgbvalacc.b, 2);
231 MAC_OUT(rgbvalacc.b, 3);
221#else 232#else
222/* generic C math */ 233/* generic C math */
223 /* add saved partial pixel from start of area */ 234 /* add saved partial pixel from start of area */
224 rgbvalacc.r = rgbvalacc.r * h_o_val + rgbvaltmp.r * mul; 235 rgbvalacc.r = rgbvalacc.r * h_o_val + rgbvaltmp.r * mul;
225 rgbvalacc.g = rgbvalacc.g * h_o_val + rgbvaltmp.g * mul; 236 rgbvalacc.g = rgbvalacc.g * h_o_val + rgbvaltmp.g * mul;
226 rgbvalacc.b = rgbvalacc.b * h_o_val + rgbvaltmp.b * mul; 237 rgbvalacc.b = rgbvalacc.b * h_o_val + rgbvaltmp.b * mul;
238 rgbvalacc.a = rgbvalacc.a * h_o_val + rgbvaltmp.a * mul;
227 239
228 /* get new pixel , then add its partial coverage to this area */ 240 /* get new pixel , then add its partial coverage to this area */
229 rgbvaltmp.r = part->buf->red; 241 rgbvaltmp.r = part->buf->red;
230 rgbvaltmp.g = part->buf->green; 242 rgbvaltmp.g = part->buf->green;
231 rgbvaltmp.b = part->buf->blue; 243 rgbvaltmp.b = part->buf->blue;
244 rgbvaltmp.a = part->buf->alpha;
232 mul = h_o_val - oxe; 245 mul = h_o_val - oxe;
233 rgbvalacc.r += rgbvaltmp.r * mul; 246 rgbvalacc.r += rgbvaltmp.r * mul;
234 rgbvalacc.g += rgbvaltmp.g * mul; 247 rgbvalacc.g += rgbvaltmp.g * mul;
235 rgbvalacc.b += rgbvaltmp.b * mul; 248 rgbvalacc.b += rgbvaltmp.b * mul;
249 rgbvalacc.a += rgbvaltmp.a * mul;
236#endif /* CPU */ 250#endif /* CPU */
237 rgbvalacc.r = (rgbvalacc.r + (1 << 21)) >> 22; 251 rgbvalacc.r = (rgbvalacc.r + (1 << 21)) >> 22;
238 rgbvalacc.g = (rgbvalacc.g + (1 << 21)) >> 22; 252 rgbvalacc.g = (rgbvalacc.g + (1 << 21)) >> 22;
239 rgbvalacc.b = (rgbvalacc.b + (1 << 21)) >> 22; 253 rgbvalacc.b = (rgbvalacc.b + (1 << 21)) >> 22;
254 rgbvalacc.a = (rgbvalacc.a + (1 << 21)) >> 22;
240 /* store or accumulate to output row */ 255 /* store or accumulate to output row */
241 if (accum) 256 if (accum)
242 { 257 {
243 rgbvalacc.r += out_line[ox].r; 258 rgbvalacc.r += out_line[ox].r;
244 rgbvalacc.g += out_line[ox].g; 259 rgbvalacc.g += out_line[ox].g;
245 rgbvalacc.b += out_line[ox].b; 260 rgbvalacc.b += out_line[ox].b;
261 rgbvalacc.a += out_line[ox].a;
246 } 262 }
247 out_line[ox].r = rgbvalacc.r; 263 out_line[ox].r = rgbvalacc.r;
248 out_line[ox].g = rgbvalacc.g; 264 out_line[ox].g = rgbvalacc.g;
249 out_line[ox].b = rgbvalacc.b; 265 out_line[ox].b = rgbvalacc.b;
266 out_line[ox].a = rgbvalacc.a;
250 /* reset accumulator */ 267 /* reset accumulator */
251 rgbvalacc.r = 0; 268 rgbvalacc.r = 0;
252 rgbvalacc.g = 0; 269 rgbvalacc.g = 0;
253 rgbvalacc.b = 0; 270 rgbvalacc.b = 0;
271 rgbvalacc.a = 0;
254 mul = oxe; 272 mul = oxe;
255 ox += 1; 273 ox += 1;
256 /* inside an area */ 274 /* inside an area */
@@ -259,6 +277,7 @@ static bool scale_h_area(void *out_line_ptr,
259 rgbvalacc.r += part->buf->red; 277 rgbvalacc.r += part->buf->red;
260 rgbvalacc.g += part->buf->green; 278 rgbvalacc.g += part->buf->green;
261 rgbvalacc.b += part->buf->blue; 279 rgbvalacc.b += part->buf->blue;
280 rgbvalacc.a += part->buf->alpha;
262 } 281 }
263#else 282#else
264 if (oxe >= h_i_val) 283 if (oxe >= h_i_val)
@@ -337,17 +356,10 @@ static inline bool scale_v_area(struct rowset *rset, struct scaler_context *ctx)
337 mul = 0; 356 mul = 0;
338 oy = rset->rowstart; 357 oy = rset->rowstart;
339 oye = 0; 358 oye = 0;
340#ifdef HAVE_LCD_COLOR
341 uint32_t *rowacc = (uint32_t *) ctx->buf, 359 uint32_t *rowacc = (uint32_t *) ctx->buf,
342 *rowtmp = rowacc + 3 * ctx->bm->width, 360 *rowtmp = rowacc + ctx->bm->width * CHANNEL_BYTES,
343 *rowacc_px, *rowtmp_px; 361 *rowacc_px, *rowtmp_px;
344 memset((void *)ctx->buf, 0, ctx->bm->width * 2 * sizeof(struct uint32_rgb)); 362 memset((void *)ctx->buf, 0, ctx->bm->width * 2 * sizeof(uint32_t)*CHANNEL_BYTES);
345#else
346 uint32_t *rowacc = (uint32_t *) ctx->buf,
347 *rowtmp = rowacc + ctx->bm->width,
348 *rowacc_px, *rowtmp_px;
349 memset((void *)ctx->buf, 0, ctx->bm->width * 2 * sizeof(uint32_t));
350#endif
351 SDEBUGF("scale_v_area\n"); 363 SDEBUGF("scale_v_area\n");
352 /* zero the accumulator and temp rows */ 364 /* zero the accumulator and temp rows */
353 for (iy = 0; iy < (unsigned int)ctx->src->height; iy++) 365 for (iy = 0; iy < (unsigned int)ctx->src->height; iy++)
@@ -376,11 +388,7 @@ static inline bool scale_v_area(struct rowset *rset, struct scaler_context *ctx)
376 *rowacc_px += mul * *rowtmp_px; 388 *rowacc_px += mul * *rowtmp_px;
377 ctx->output_row(oy, (void*)rowacc, ctx); 389 ctx->output_row(oy, (void*)rowacc, ctx);
378 /* clear accumulator row, store partial coverage for next row */ 390 /* clear accumulator row, store partial coverage for next row */
379#ifdef HAVE_LCD_COLOR 391 memset((void *)rowacc, 0, ctx->bm->width * sizeof(uint32_t) * CHANNEL_BYTES);
380 memset((void *)rowacc, 0, ctx->bm->width * sizeof(uint32_t) * 3);
381#else
382 memset((void *)rowacc, 0, ctx->bm->width * sizeof(uint32_t));
383#endif
384 mul = oye; 392 mul = oye;
385 oy += rset->rowstep; 393 oy += rset->rowstep;
386 /* inside an area */ 394 /* inside an area */
@@ -411,8 +419,8 @@ static bool scale_h_linear(void *out_line_ptr, struct scaler_context *ctx,
411 set such that this will occur before these are used. 419 set such that this will occur before these are used.
412 */ 420 */
413#ifdef HAVE_LCD_COLOR 421#ifdef HAVE_LCD_COLOR
414 struct uint32_rgb rgbval=rgbval, rgbinc=rgbinc, 422 struct uint32_argb rgbval=rgbval, rgbinc=rgbinc,
415 *out_line = (struct uint32_rgb*)out_line_ptr; 423 *out_line = (struct uint32_argb*)out_line_ptr;
416#else 424#else
417 uint32_t val=val, inc=inc, *out_line = (uint32_t*)out_line_ptr; 425 uint32_t val=val, inc=inc, *out_line = (uint32_t*)out_line_ptr;
418#endif 426#endif
@@ -436,16 +444,19 @@ static bool scale_h_linear(void *out_line_ptr, struct scaler_context *ctx,
436 rgbinc.r = -(part->buf->red); 444 rgbinc.r = -(part->buf->red);
437 rgbinc.g = -(part->buf->green); 445 rgbinc.g = -(part->buf->green);
438 rgbinc.b = -(part->buf->blue); 446 rgbinc.b = -(part->buf->blue);
447 rgbinc.a = -(part->buf->alpha);
439#if defined(CPU_COLDFIRE) 448#if defined(CPU_COLDFIRE)
440/* Coldfire EMAC math */ 449/* Coldfire EMAC math */
441 MAC(part->buf->red, h_o_val, 0); 450 MAC(part->buf->red, h_o_val, 0);
442 MAC(part->buf->green, h_o_val, 1); 451 MAC(part->buf->green, h_o_val, 1);
443 MAC(part->buf->blue, h_o_val, 2); 452 MAC(part->buf->blue, h_o_val, 2);
453 MAC(part->buf->alpha, h_o_val, 3);
444#else 454#else
445/* generic C math */ 455/* generic C math */
446 rgbval.r = (part->buf->red) * h_o_val; 456 rgbval.r = (part->buf->red) * h_o_val;
447 rgbval.g = (part->buf->green) * h_o_val; 457 rgbval.g = (part->buf->green) * h_o_val;
448 rgbval.b = (part->buf->blue) * h_o_val; 458 rgbval.b = (part->buf->blue) * h_o_val;
459 rgbval.a = (part->buf->alpha) * h_o_val;
449#endif /* CPU */ 460#endif /* CPU */
450 ix += 1; 461 ix += 1;
451 /* If this wasn't the last pixel, add the next one to rgbinc. */ 462 /* If this wasn't the last pixel, add the next one to rgbinc. */
@@ -457,6 +468,7 @@ static bool scale_h_linear(void *out_line_ptr, struct scaler_context *ctx,
457 rgbinc.r += part->buf->red; 468 rgbinc.r += part->buf->red;
458 rgbinc.g += part->buf->green; 469 rgbinc.g += part->buf->green;
459 rgbinc.b += part->buf->blue; 470 rgbinc.b += part->buf->blue;
471 rgbinc.a += part->buf->alpha;
460 /* Add a partial step to rgbval, in this pixel isn't precisely 472 /* Add a partial step to rgbval, in this pixel isn't precisely
461 aligned with the new source pixel 473 aligned with the new source pixel
462 */ 474 */
@@ -465,11 +477,13 @@ static bool scale_h_linear(void *out_line_ptr, struct scaler_context *ctx,
465 MAC(rgbinc.r, ixe, 0); 477 MAC(rgbinc.r, ixe, 0);
466 MAC(rgbinc.g, ixe, 1); 478 MAC(rgbinc.g, ixe, 1);
467 MAC(rgbinc.b, ixe, 2); 479 MAC(rgbinc.b, ixe, 2);
480 MAC(rgbinc.a, ixe, 3);
468#else 481#else
469/* generic C math */ 482/* generic C math */
470 rgbval.r += rgbinc.r * ixe; 483 rgbval.r += rgbinc.r * ixe;
471 rgbval.g += rgbinc.g * ixe; 484 rgbval.g += rgbinc.g * ixe;
472 rgbval.b += rgbinc.b * ixe; 485 rgbval.b += rgbinc.b * ixe;
486 rgbval.a += rgbinc.a * ixe;
473#endif 487#endif
474 } 488 }
475#if defined(CPU_COLDFIRE) 489#if defined(CPU_COLDFIRE)
@@ -477,15 +491,18 @@ static bool scale_h_linear(void *out_line_ptr, struct scaler_context *ctx,
477 MAC_OUT(rgbval.r, 0); 491 MAC_OUT(rgbval.r, 0);
478 MAC_OUT(rgbval.g, 1); 492 MAC_OUT(rgbval.g, 1);
479 MAC_OUT(rgbval.b, 2); 493 MAC_OUT(rgbval.b, 2);
494 MAC_OUT(rgbval.a, 3);
480#endif 495#endif
481 /* Now multiply the color increment to its proper value */ 496 /* Now multiply the color increment to its proper value */
482 rgbinc.r *= h_i_val; 497 rgbinc.r *= h_i_val;
483 rgbinc.g *= h_i_val; 498 rgbinc.g *= h_i_val;
484 rgbinc.b *= h_i_val; 499 rgbinc.b *= h_i_val;
500 rgbinc.a *= h_i_val;
485 } else { 501 } else {
486 rgbval.r += rgbinc.r; 502 rgbval.r += rgbinc.r;
487 rgbval.g += rgbinc.g; 503 rgbval.g += rgbinc.g;
488 rgbval.b += rgbinc.b; 504 rgbval.b += rgbinc.b;
505 rgbval.a += rgbinc.a;
489 } 506 }
490 /* round and scale values, and accumulate or store to output */ 507 /* round and scale values, and accumulate or store to output */
491 if (accum) 508 if (accum)
@@ -493,10 +510,12 @@ static bool scale_h_linear(void *out_line_ptr, struct scaler_context *ctx,
493 out_line[ox].r += (rgbval.r + (1 << 21)) >> 22; 510 out_line[ox].r += (rgbval.r + (1 << 21)) >> 22;
494 out_line[ox].g += (rgbval.g + (1 << 21)) >> 22; 511 out_line[ox].g += (rgbval.g + (1 << 21)) >> 22;
495 out_line[ox].b += (rgbval.b + (1 << 21)) >> 22; 512 out_line[ox].b += (rgbval.b + (1 << 21)) >> 22;
513 out_line[ox].a += (rgbval.a + (1 << 21)) >> 22;
496 } else { 514 } else {
497 out_line[ox].r = (rgbval.r + (1 << 21)) >> 22; 515 out_line[ox].r = (rgbval.r + (1 << 21)) >> 22;
498 out_line[ox].g = (rgbval.g + (1 << 21)) >> 22; 516 out_line[ox].g = (rgbval.g + (1 << 21)) >> 22;
499 out_line[ox].b = (rgbval.b + (1 << 21)) >> 22; 517 out_line[ox].b = (rgbval.b + (1 << 21)) >> 22;
518 out_line[ox].a = (rgbval.a + (1 << 21)) >> 22;
500 } 519 }
501#else 520#else
502 if (ixe >= h_o_val) 521 if (ixe >= h_o_val)
@@ -592,15 +611,9 @@ static inline bool scale_v_linear(struct rowset *rset,
592 /* Set up our buffers, to store the increment and current value for each 611 /* Set up our buffers, to store the increment and current value for each
593 column, and one temp buffer used to read in new rows. 612 column, and one temp buffer used to read in new rows.
594 */ 613 */
595#ifdef HAVE_LCD_COLOR
596 uint32_t *rowinc = (uint32_t *)(ctx->buf),
597 *rowval = rowinc + 3 * ctx->bm->width,
598 *rowtmp = rowval + 3 * ctx->bm->width,
599#else
600 uint32_t *rowinc = (uint32_t *)(ctx->buf), 614 uint32_t *rowinc = (uint32_t *)(ctx->buf),
601 *rowval = rowinc + ctx->bm->width, 615 *rowval = rowinc + ctx->bm->width * CHANNEL_BYTES,
602 *rowtmp = rowval + ctx->bm->width, 616 *rowtmp = rowval + ctx->bm->width * CHANNEL_BYTES,
603#endif
604 *rowinc_px, *rowval_px, *rowtmp_px; 617 *rowinc_px, *rowval_px, *rowtmp_px;
605 618
606 SDEBUGF("scale_v_linear\n"); 619 SDEBUGF("scale_v_linear\n");
@@ -658,7 +671,7 @@ static void output_row_32_native_fromyuv(uint32_t row, void * row_in,
658 671
659 int col; 672 int col;
660 uint8_t dy = DITHERY(row); 673 uint8_t dy = DITHERY(row);
661 struct uint32_rgb *qp = (struct uint32_rgb *)row_in; 674 struct uint32_argb *qp = (struct uint32_argb *)row_in;
662 SDEBUGF("output_row: y: %lu in: %p\n",row, row_in); 675 SDEBUGF("output_row: y: %lu in: %p\n",row, row_in);
663 fb_data *dest = (fb_data *)ctx->bm->data + Y_STEP * row; 676 fb_data *dest = (fb_data *)ctx->bm->data + Y_STEP * row;
664 int delta = 127; 677 int delta = 127;
@@ -689,7 +702,7 @@ static void output_row_32_native(uint32_t row, void * row_in,
689 int fb_width = BM_WIDTH(ctx->bm->width,FORMAT_NATIVE,0); 702 int fb_width = BM_WIDTH(ctx->bm->width,FORMAT_NATIVE,0);
690 uint8_t dy = DITHERY(row); 703 uint8_t dy = DITHERY(row);
691#ifdef HAVE_LCD_COLOR 704#ifdef HAVE_LCD_COLOR
692 struct uint32_rgb *qp = (struct uint32_rgb*)row_in; 705 struct uint32_argb *qp = (struct uint32_argb*)row_in;
693#else 706#else
694 uint32_t *qp = (uint32_t*)row_in; 707 uint32_t *qp = (uint32_t*)row_in;
695#endif 708#endif
@@ -750,34 +763,19 @@ static void output_row_32_native(uint32_t row, void * row_in,
750 } 763 }
751#endif /* LCD_PIXELFORMAT */ 764#endif /* LCD_PIXELFORMAT */
752#elif LCD_DEPTH == 16 765#elif LCD_DEPTH == 16
753
754#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
755 /* M:Robe 500 */
756 (void) fb_width;
757 fb_data *dest = (fb_data *)ctx->bm->data + row;
758 int delta = 127;
759 unsigned r, g, b;
760 struct uint32_rgb q0;
761
762 for (col = 0; col < ctx->bm->width; col++) {
763 if (ctx->dither)
764 delta = DITHERXDY(col,dy);
765 q0 = *qp++;
766 r = SC_OUT(q0.r, ctx);
767 g = SC_OUT(q0.g, ctx);
768 b = SC_OUT(q0.b, ctx);
769 r = (31 * r + (r >> 3) + delta) >> 8;
770 g = (63 * g + (g >> 2) + delta) >> 8;
771 b = (31 * b + (b >> 3) + delta) >> 8;
772 *dest = LCD_RGBPACK_LCD(r, g, b);
773 dest += ctx->bm->height;
774 }
775#else
776 /* iriver h300, colour iPods, X5 */ 766 /* iriver h300, colour iPods, X5 */
777 fb_data *dest = (fb_data *)ctx->bm->data + fb_width * row; 767 (void)fb_width;
768 fb_data *dest = STRIDE_MAIN((fb_data *)ctx->bm->data + fb_width * row,
769 (fb_data *)ctx->bm->data + row);
778 int delta = 127; 770 int delta = 127;
779 unsigned r, g, b; 771 unsigned r, g, b;
780 struct uint32_rgb q0; 772 struct uint32_argb q0;
773 /* setup alpha channel buffer */
774 unsigned char *bm_alpha = NULL;
775 if (ctx->bm->alpha_offset > 0)
776 bm_alpha = ctx->bm->data + ctx->bm->alpha_offset;
777 if (bm_alpha)
778 bm_alpha += ctx->bm->width*row/2;
781 779
782 for (col = 0; col < ctx->bm->width; col++) { 780 for (col = 0; col < ctx->bm->width; col++) {
783 if (ctx->dither) 781 if (ctx->dither)
@@ -789,10 +787,17 @@ static void output_row_32_native(uint32_t row, void * row_in,
789 r = (31 * r + (r >> 3) + delta) >> 8; 787 r = (31 * r + (r >> 3) + delta) >> 8;
790 g = (63 * g + (g >> 2) + delta) >> 8; 788 g = (63 * g + (g >> 2) + delta) >> 8;
791 b = (31 * b + (b >> 3) + delta) >> 8; 789 b = (31 * b + (b >> 3) + delta) >> 8;
792 *dest++ = LCD_RGBPACK_LCD(r, g, b); 790 *dest = LCD_RGBPACK_LCD(r, g, b);
791 dest += STRIDE_MAIN(1, ctx->bm->height);
792 if (bm_alpha) {
793 /* pack alpha channel for 2 pixels into 1 byte */
794 unsigned alpha = 255-SC_OUT(q0.a, ctx);
795 if (col%2)
796 *bm_alpha++ |= alpha&0xf0;
797 else
798 *bm_alpha = alpha>>4;
799 }
793 } 800 }
794#endif
795
796#endif /* LCD_DEPTH */ 801#endif /* LCD_DEPTH */
797} 802}
798#endif 803#endif
@@ -829,8 +834,9 @@ int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
829 const int dw = bm->width; 834 const int dw = bm->width;
830 const int dh = bm->height; 835 const int dh = bm->height;
831 int ret; 836 int ret;
837 /* buffer for 1 line + 2 spare lines */
832#ifdef HAVE_LCD_COLOR 838#ifdef HAVE_LCD_COLOR
833 unsigned int needed = sizeof(struct uint32_rgb) * 3 * bm->width; 839 unsigned int needed = sizeof(struct uint32_argb) * 3 * bm->width;
834#else 840#else
835 unsigned int needed = sizeof(uint32_t) * 3 * bm->width; 841 unsigned int needed = sizeof(uint32_t) * 3 * bm->width;
836#endif 842#endif
diff --git a/apps/recorder/resize.h b/apps/recorder/resize.h
index d71a3e7f1c..7e0a991eea 100644
--- a/apps/recorder/resize.h
+++ b/apps/recorder/resize.h
@@ -113,10 +113,11 @@ struct img_part {
113/* intermediate type used by the scaler for color output. greyscale version 113/* intermediate type used by the scaler for color output. greyscale version
114 uses uint32_t 114 uses uint32_t
115*/ 115*/
116struct uint32_rgb { 116struct uint32_argb {
117 uint32_t r; 117 uint32_t r;
118 uint32_t g; 118 uint32_t g;
119 uint32_t b; 119 uint32_t b;
120 uint32_t a;
120}; 121};
121#endif 122#endif
122 123