diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2007-10-31 10:24:08 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2007-10-31 10:24:08 (GMT) |
commit | 8cff39c2e6ce28a548c13c2f71f991658686e7d1 (patch) | |
tree | 53d654c36c9a37987ba4d10a24bfd5dbd4f9404a /generic | |
parent | 644cecc295e9fd371226e9c5b3eeeb50b0181b41 (diff) | |
download | tk-8cff39c2e6ce28a548c13c2f71f991658686e7d1.zip tk-8cff39c2e6ce28a548c13c2f71f991658686e7d1.tar.gz tk-8cff39c2e6ce28a548c13c2f71f991658686e7d1.tar.bz2 |
Improve Tk_PhotoPutBlock a bit more. Derived from [Patch 224066]
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkImgPhoto.c | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 88d3603..a2e814a 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -17,7 +17,7 @@ * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPhoto.c,v 1.74 2007/10/30 15:34:57 dkf Exp $ + * RCS: @(#) $Id: tkImgPhoto.c,v 1.75 2007/10/31 10:24:09 dkf Exp $ */ #include "tkInt.h" @@ -4424,6 +4424,9 @@ Tk_PhotoPutBlock( */ for (hLeft = height; hLeft > 0;) { + int pixelSize = blockPtr->pixelSize; + int compRuleSet = (compRule == TK_PHOTO_COMPOSITE_SET); + srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0]; hCopy = MIN(hLeft, blockPtr->height); hLeft -= hCopy; @@ -4434,10 +4437,10 @@ Tk_PhotoPutBlock( * much faster. */ - if ((blockPtr->pixelSize == 4) && (greenOffset == 1) + if ((pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) && (width <= blockPtr->width) - && (compRule == TK_PHOTO_COMPOSITE_SET)) { + && compRuleSet) { memcpy(destLinePtr, srcLinePtr, (size_t) (width * 4)); srcLinePtr += blockPtr->pitch; destLinePtr += pitch; @@ -4453,35 +4456,56 @@ Tk_PhotoPutBlock( wCopy = MIN(wLeft, blockPtr->width); wLeft -= wCopy; srcPtr = srcLinePtr; - for (; wCopy>0 ; --wCopy, srcPtr+=blockPtr->pixelSize) { - int alpha = srcPtr[alphaOffset]; + /* + * But we might be lucky and be able to use fairly fast loops. + * It's worth checking... + */ + + if (alphaOffset == 0) { /* - * In the easy case, we can just copy. + * This is the non-alpha case, so can still be fairly + * fast. Note that in the non-alpha-source case, the + * compositing rule doesn't apply. */ - if (!alphaOffset || (alpha == 255)) { - /* - * New solid part of the image. - */ - + for (; wCopy>0 ; --wCopy, srcPtr+=pixelSize) { *destPtr++ = srcPtr[0]; *destPtr++ = srcPtr[greenOffset]; *destPtr++ = srcPtr[blueOffset]; *destPtr++ = 255; - continue; } - + continue; + } else if (compRuleSet) { /* - * Combine according to the compositing rule. + * This is the SET compositing rule, which just replaces + * what was there before with the new data. This is + * another fairly fast case. No point in doing a memcpy(); + * the order of channels is probably wrong. */ - if ((compRule == TK_PHOTO_COMPOSITE_SET) || !destPtr[3]) { + for (; wCopy>0 ; --wCopy, srcPtr+=pixelSize) { + *destPtr++ = srcPtr[0]; + *destPtr++ = srcPtr[greenOffset]; + *destPtr++ = srcPtr[blueOffset]; + *destPtr++ = srcPtr[alphaOffset]; + } + continue; + } + + /* + * Bother; need to consider the alpha value of each pixel to + * know what to do. + */ + + for (; wCopy>0 ; --wCopy, srcPtr+=pixelSize) { + int alpha = srcPtr[alphaOffset]; + + if (alpha == 255 || !destPtr[3]) { /* - * Either this is the SET rule (we overwrite whatever - * is there) or the destination is entirely blank. In - * both cases, we just set the destination to the - * source. + * Either the source is 100% opaque, or the + * destination is entirely blank. In all cases, we + * just set the destination to the source. */ *destPtr++ = srcPtr[0]; @@ -4491,12 +4515,20 @@ Tk_PhotoPutBlock( continue; } + /* + * Can still skip doing work if the source is 100% + * transparent at this point. + */ + if (alpha) { int Alpha = destPtr[3]; /* - * This implements the Porter-Duff Source-Over - * compositing rule. + * OK, there's real work to be done. Luckily, there's + * a substantial literature on what to do in this + * case. In particular, Porter and Duff have done a + * taxonomy of compositing rules, and the right one is + * the "Source Over" rule. This code implements that. */ destPtr[0] = PD_SRC_OVER(srcPtr[0], alpha, destPtr[0], @@ -4508,10 +4540,6 @@ Tk_PhotoPutBlock( destPtr[3] = PD_SRC_OVER_ALPHA(alpha, Alpha); } - /* - * else should be empty space - */ - destPtr += 4; } } |