From c738d9d9549e3c8093ce4a6ebd2e63d13c9ca1bc Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 20 Mar 2010 19:14:58 +0000 Subject: Special fast case for PBM enlargement by 4, 6, 7, 8, 9, and 10 (added to existing fast cases for 1, 2, 3, and 5) git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1153 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- editor/pamenlarge.c | 143 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 121 insertions(+), 22 deletions(-) (limited to 'editor/pamenlarge.c') diff --git a/editor/pamenlarge.c b/editor/pamenlarge.c index b3039424..dd61f2cf 100644 --- a/editor/pamenlarge.c +++ b/editor/pamenlarge.c @@ -115,6 +115,8 @@ enlargePbmRowHorizontally(struct pam * const inpamP, static unsigned char const trp3[8] = { 0x00, 0x07, 0x38, 0x3F, 0xC0, 0xC7, 0xF8, 0xFF }; + static unsigned char const quad[4] = { 0x00, 0x0F, 0xF0, 0xFF }; + static unsigned char const quin2[8] = { 0x00, 0x01, 0x3E, 0x3F, 0xC0, 0xC1, 0xFE, 0xFF }; @@ -129,33 +131,127 @@ enlargePbmRowHorizontally(struct pam * const inpamP, case 1: break; /* outrow set to inrow */ case 2: /* Make outrow using prefabricated parts (same for 3, 5). */ for (colChar = 0; colChar < inColChars; ++colChar) { - outrow[colChar*2] = dbl[(inrow[colChar] & 0xF0) >> 4]; - outrow[colChar*2+1]= dbl[inrow[colChar] & 0x0F]; + outrow[colChar*2] = dbl[(inrow[colChar] & 0xF0) >> 4]; + outrow[colChar*2+1] = dbl[(inrow[colChar] & 0x0F) >> 0]; /* Possible outrow overrun by one byte. */ } - break; + break; + case 3: for (colChar = 0; colChar < inColChars; ++colChar) { - outrow[colChar*3] = trp1[(inrow[colChar] & 0xF0) >> 5]; - outrow[colChar*3+1]= trp2[(inrow[colChar] >> 2) & 0x0F]; - outrow[colChar*3+2]= trp3[inrow[colChar] & 0x07]; + outrow[colChar*3] = trp1[(inrow[colChar] & 0xF0) >> 5]; + outrow[colChar*3+1] = trp2[(inrow[colChar] >> 2) & 0x0F]; + outrow[colChar*3+2] = trp3[(inrow[colChar] >> 0) & 0x07]; } break; + + case 4: + for (colChar = 0; colChar < inColChars; ++colChar) { + unsigned int i; + for (i = 0; i < 4; ++i) + outrow[colChar*4+i]= + quad[(inrow[colChar] >> (6 - 2 * i)) & 0x03]; + } + break; + case 5: for (colChar = 0; colChar < inColChars; ++colChar) { - outrow[colChar*5] = pair[ (inrow[colChar] >>6) & 0x03 ] >> 5; - outrow[colChar*5+1]= quin2[(inrow[colChar] >>4) & 0x07 ]; - outrow[colChar*5+2]= pair[ (inrow[colChar] >>3) & 0x03 ] >> 4; - outrow[colChar*5+3]= quin4[(inrow[colChar] >>1) & 0x07 ]; - outrow[colChar*5+4]= pair[ inrow[colChar] & 0x03 ] >>3; + outrow[colChar*5] = pair [(inrow[colChar] >> 6) & 0x03] >> 5; + outrow[colChar*5+1] = quin2[(inrow[colChar] >> 4) & 0x07] >> 0; + outrow[colChar*5+2] = quad [(inrow[colChar] >> 3) & 0x03] >> 0; + outrow[colChar*5+3] = quin4[(inrow[colChar] >> 1) & 0x07] >> 0; + outrow[colChar*5+4] = pair [(inrow[colChar] >> 0) & 0x03] >> 3; + } + break; + + case 6: /* Compound of 2 and 3 */ + for (colChar = 0; colChar < inColChars; ++colChar) { + unsigned char const hi = dbl[(inrow[colChar] & 0xF0) >> 4]; + unsigned char const lo = dbl[(inrow[colChar] & 0x0F) >> 0]; + + outrow[colChar*6] = trp1[(hi & 0xF0) >> 5]; + outrow[colChar*6+1] = trp2[(hi >> 2) & 0x0F]; + outrow[colChar*6+2] = trp3[hi & 0x07]; + + outrow[colChar*6+3] = trp1[(lo & 0xF0) >> 5]; + outrow[colChar*6+4] = trp2[(lo >> 2) & 0x0F]; + outrow[colChar*6+5] = trp3[lo & 0x07]; + } + break; + + case 7: + for (colChar = 0; colChar < inColChars; ++colChar) { + uint32_t hi, lo; + + hi = inrow[colChar] >> 4; + hi = ((((hi>>1) * 0x00082080) | (0x01 & hi)) & 0x00204081 ) * 0x7F; + hi >>= 4; + outrow[colChar*7] = (unsigned char) ( hi >> 16); + outrow[colChar*7+1] = (unsigned char) ((hi >> 8) & 0xFF); + outrow[colChar*7+2] = (unsigned char) ((hi >> 0) & 0xFF); + + lo = inrow[colChar] & 0x001F; + lo = ((((lo>>1) * 0x02082080) | (0x01 & lo)) & 0x10204081 ) * 0x7F; + outrow[colChar*7+3] = (unsigned char) ((lo >> 24) & 0xFF); + outrow[colChar*7+4] = (unsigned char) ((lo >> 16) & 0xFF); + outrow[colChar*7+5] = (unsigned char) ((lo >> 8) & 0xFF); + outrow[colChar*7+6] = (unsigned char) ((lo >> 0) & 0xFF); + } + break; + + case 8: + for (colChar = 0; colChar < inColChars; ++colChar) { + unsigned int i; + for (i = 0; i < 8; ++i) { + outrow[colChar*8+i] = + ((inrow[colChar] >> (7-i)) & 0x01) *0xFF; + } + } + break; + + case 9: + for (colChar = 0; colChar < inColChars; ++colChar) { + outrow[colChar*9] = ((inrow[colChar] >> 7) & 0x01) * 0xFF; + outrow[colChar*9+1] = pair[(inrow[colChar] >> 6) & 0x03] >> 1; + outrow[colChar*9+2] = pair[(inrow[colChar] >> 5) & 0x03] >> 2; + outrow[colChar*9+3] = pair[(inrow[colChar] >> 4) & 0x03] >> 3; + outrow[colChar*9+4] = pair[(inrow[colChar] >> 3) & 0x03] >> 4; + outrow[colChar*9+5] = pair[(inrow[colChar] >> 2) & 0x03] >> 5; + outrow[colChar*9+6] = pair[(inrow[colChar] >> 1) & 0x03] >> 6; + outrow[colChar*9+7] = pair[(inrow[colChar] >> 0) & 0x03] >> 7; + outrow[colChar*9+8] = (inrow[colChar] & 0x01) * 0xFF; + } + break; + + case 10: + for (colChar = 0; colChar < inColChars; ++colChar) { + outrow[colChar*10] = ((inrow[colChar] >> 7) & 0x01 ) * 0xFF; + outrow[colChar*10+1] = pair[(inrow[colChar] >> 6) & 0x03] >> 2; + outrow[colChar*10+2] = pair[(inrow[colChar] >> 5) & 0x03] >> 4; + outrow[colChar*10+3] = pair[(inrow[colChar] >> 4) & 0x03] >> 6; + outrow[colChar*10+4] = ((inrow[colChar] >> 4) & 0x01) * 0xFF; + outrow[colChar*10+5] = ((inrow[colChar] >> 3) & 0x01) * 0xFF; + outrow[colChar*10+6] = pair[(inrow[colChar] >> 2) & 0x03] >> 2; + outrow[colChar*10+7] = pair[(inrow[colChar] >> 1) & 0x03] >> 4; + outrow[colChar*10+8] = pair[(inrow[colChar] >> 0) & 0x03] >> 6; + outrow[colChar*10+9] = ((inrow[colChar] >> 0) & 0x01) * 0xFF; } break; - case 4: default: - /* Unlike the above cases, we iterate through outrow. The color - composition of each outrow byte is computed by consulting - a single bit or two consecutive bits in inrow. + + + default: + /* Unlike the above cases, we iterate through outrow. To compute the + color composition of each outrow byte, we consult a single bit or + two consecutive bits in inrow. + Color changes never happen twice in a single outrow byte. + + This is a generalization of above routines for scale factors + 9 and 10. + + Logic works for scale factors 4, 6, 7, 8, and above (but not 5). */ + for (colChar = 0; colChar < outColChars; ++colChar) { unsigned int const mult = scaleFactor; unsigned int const mod = colChar % mult; @@ -199,12 +295,14 @@ enlargePbm(struct pam * const inpamP, if (scaleFactor == 1) outrow = inrow; - else - outrow = pbm_allocrow_packed(outcols + 32); - /* The 32 (=4 bytes) is to allow writes beyond outrow data - end when scaleFactor is 2, 3, 5. (max 4 bytes when - scaleFactor is 5) - */ + else { + /* Allow writes beyond outrow data end when scaleFactor is + one of the special fast cases: 2, 3, 4, 5, 6, 7, 8, 9, 10. + */ + unsigned int const rightPadding = + scaleFactor > 10 ? 0 : (scaleFactor - 1) * 8; + outrow = pbm_allocrow_packed(outcols + rightPadding); + } pbm_writepbminit(ofP, outcols, outrows, 0); @@ -214,7 +312,8 @@ enlargePbm(struct pam * const inpamP, pbm_readpbmrow_packed(inpamP->file, inrow, inpamP->width, inpamP->format); - if (inpamP->width % 8 > 0) { /* clean final partial byte */ + if (outcols % 8 > 0) { + /* clean final partial byte */ inrow[inColChars-1] >>= 8 - inpamP->width % 8; inrow[inColChars-1] <<= 8 - inpamP->width % 8; } -- cgit 1.4.1