diff options
author | Thomas Martitz <kugel@rockbox.org> | 2011-11-08 21:39:23 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2011-11-08 21:39:23 +0000 |
commit | c7b8054714cff4580ddbdbf5c9d503b20ff45740 (patch) | |
tree | 20e896da7940e667e5696a7dafaffebd337783df /apps/recorder/resize.c | |
parent | f443e7bbf7771ce3a79b1c2116b9cf216f15938f (diff) | |
download | rockbox-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
Diffstat (limited to 'apps/recorder/resize.c')
-rw-r--r-- | apps/recorder/resize.c | 122 |
1 files changed, 64 insertions, 58 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 |