@@ -514,46 +514,65 @@ void InvertBytes(uint8_t *pData, uint8_t bLen)
514514 }
515515} /* InvertBytes() */
516516//
517- // Load a 1-bpp Group5 compressed bitmap
517+ // Load a 1-bpp Group5 compressed bitmap at the given scale
518518// Pass the pointer to the beginning of the G5 file
519- // If the FG == BG color, and there is a back buffer, it will
520- // draw the 1's bits as the FG color and leave
521- // the background (0 pixels) unchanged - aka transparent.
519+ // If the FG == BG color, it will draw the 1's bits
520+ // as the FG color and leave the background (0 bits)
521+ // unchanged - aka transparent.
522522//
523- int bbepLoadG5 (FASTEPDSTATE *pBBEP, const uint8_t *pG5, int x, int y, int iFG, int iBG)
523+ int bbepLoadG5 (FASTEPDSTATE *pBBEP, const uint8_t *pG5, int x, int y, int iFG, int iBG, float fScale )
524524{
525- uint16_t rc, tx, ty, cx, cy, size;
525+ uint16_t rc, tx, ty, dx, dy, cx, cy, size;
526+ uint16_t width, height;
526527 BB_BITMAP *pbbb;
527-
528- if (pBBEP == NULL || pG5 == NULL ) return BBEP_ERROR_BAD_PARAMETER;
528+ uint32_t u32Frac, u32XAcc, u32YAcc; // integer fraction vars
529+
530+ if (pBBEP == NULL || pG5 == NULL || fScale < 0.01 ) return BBEP_ERROR_BAD_PARAMETER;
531+ u32Frac = (uint32_t )(65536 .0f / fScale ); // calculate the fraction to advance the destination x/y
529532 pbbb = (BB_BITMAP *)pG5;
530533 if (pgm_read_word (&pbbb->u16Marker ) != BB_BITMAP_MARKER) return BBEP_ERROR_BAD_DATA;
534+ width = pBBEP->width ;
535+ height = pBBEP->height ;
531536 cx = pgm_read_word (&pbbb->width );
532537 cy = pgm_read_word (&pbbb->height );
538+ // Calculate scaled destination size
539+ dx = (int )(fScale * (float )cx);
540+ dy = (int )(fScale * (float )cy);
533541 size = pgm_read_word (&pbbb->size );
534542 if (iFG == -1 ) iFG = BBEP_WHITE;
535543 if (iBG == -1 ) iBG = BBEP_BLACK;
536544 rc = g5_decode_init (&g5dec, cx, cy, (uint8_t *)&pbbb[1 ], size);
537545 if (rc != G5_SUCCESS) return BBEP_ERROR_BAD_DATA; // corrupt data?
538- for (ty=y; ty<y+cy && ty < pBBEP->height ; ty++) {
546+ u32YAcc = 65536 ; // force first line to get decoded
547+ for (ty=y; ty<y+dy && ty < height; ty++) {
539548 uint8_t u8 , *s, src_mask;
540- g5_decode_line (&g5dec, u8Cache);
541- src_mask = 0 ; // make it read a byte to start
542- s = u8Cache;
543- for (tx=x; tx<x+cx; tx++) {
549+ while (u32YAcc >= 65536 ) { // advance to next source line
550+ g5_decode_line (&g5dec, u8Cache);
551+ u32YAcc -= 65536 ;
552+ }
553+ s = u8Cache;
554+ u32XAcc = 0 ;
555+ u8 = *s++; // grab first source byte (8 pixels)
556+ src_mask = 0x80 ; // MSB on left
557+ for (tx=x; tx<x+dx && tx < width; tx++) {
558+ if (u8 & src_mask) {
559+ if (iFG != BBEP_TRANSPARENT)
560+ (*pBBEP->pfnSetPixelFast )(pBBEP, tx, ty, (uint8_t )iFG);
561+ } else {
562+ if (iBG != BBEP_TRANSPARENT)
563+ (*pBBEP->pfnSetPixelFast )(pBBEP, tx, ty, (uint8_t )iBG);
564+ }
565+ u32XAcc += u32Frac;
566+ while (u32XAcc >= 65536 ) {
567+ u32XAcc -= 65536 ; // whole source pixel horizontal movement
568+ src_mask >>= 1 ;
544569 if (src_mask == 0 ) { // need to load the next byte
545570 u8 = *s++;
546- src_mask = 0x80 ; // MSB on left
547- }
548- if (u8 & src_mask) {
549- if (iFG != BBEP_TRANSPARENT)
550- (*pBBEP->pfnSetPixelFast )(pBBEP, tx, ty, (uint8_t )iFG);
551- } else {
552- if (iBG != BBEP_TRANSPARENT)
553- (*pBBEP->pfnSetPixelFast )(pBBEP, tx, ty, (uint8_t )iBG);
571+ src_mask = 0x80 ;
554572 }
555- src_mask >>= 1 ;
556- } // for tx
573+ }
574+ } // for tx
575+ u32YAcc += u32Frac;
557576 } // for y
558577 return BBEP_SUCCESS;
559578} /* bbepLoadG5() */
0 commit comments