Fixed <rdar://problem/3882212> REGRESSION: Images clipped instead of scaled
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Nov 2004 20:31:34 +0000 (20:31 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Nov 2004 20:31:34 +0000 (20:31 +0000)
        Fixed <rdar://problem/3884088> Crash terminating image load

        Also added code to turn off color correction for images created
        via CGImageSources.  This code is currently disabled because CG
        can't change the color space of images loaded progressively.
        Further, according to Dave Hayward, CG will no longer attempt
        to color correct images that don't have embedded profiles as of
        Tiger 8A306.

        Reviewed by Chris.

        * WebCoreSupport.subproj/WebImageData.m:
        (-[WebImageData _commonTermination]):
        (-[WebImageData dealloc]):
        (-[WebImageData _invalidateImageProperties]):
        (-[WebImageData imageAtIndex:]):
        (-[WebImageData incrementalLoadWithBytes:length:complete:]):
        (-[WebImageData propertiesAtIndex:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@8028 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/ChangeLog
WebKit/WebCoreSupport.subproj/WebImageData.m

index f07ebf8bc1448c36d66861280fe6cf5eb64cb1c4..6105ecbfff7c450607c9cdeb9618a94a7d741375 100644 (file)
@@ -1,3 +1,25 @@
+2004-11-17  Richard Williamson   <rjw@apple.com>
+
+        Fixed <rdar://problem/3882212> REGRESSION: Images clipped instead of scaled
+        Fixed <rdar://problem/3884088> Crash terminating image load
+
+        Also added code to turn off color correction for images created
+        via CGImageSources.  This code is currently disabled because CG  
+        can't change the color space of images loaded progressively.
+        Further, according to Dave Hayward, CG will no longer attempt
+        to color correct images that don't have embedded profiles as of
+        Tiger 8A306.
+
+        Reviewed by Chris.
+
+        * WebCoreSupport.subproj/WebImageData.m:
+        (-[WebImageData _commonTermination]):
+        (-[WebImageData dealloc]):
+        (-[WebImageData _invalidateImageProperties]):
+        (-[WebImageData imageAtIndex:]):
+        (-[WebImageData incrementalLoadWithBytes:length:complete:]):
+        (-[WebImageData propertiesAtIndex:]):
+
 2004-11-16  Chris Blumenberg  <cblu@apple.com>
 
        Fixed: <rdar://problem/3882034> REGRESSION: Context menu incorrect for PDF content
index 66450c75cbb8257fd18d9f1a813732ef3599af6d..c1a80df597b3412cde1f0b559442095d93946afd 100644 (file)
@@ -12,6 +12,7 @@
 
 #import <CoreGraphics/CGContextPrivate.h>
 #import <CoreGraphics/CGContextGState.h>
+#import <CoreGraphics/CGColorSpacePrivate.h>
 
 #ifdef USE_CGIMAGEREF
 
@@ -21,6 +22,7 @@ static CFDictionaryRef imageSourceOptions;
 @interface WebImageData (WebInternal)
 - (void)_commonTermination;
 - (void)_invalidateImages;
+- (void)_invalidateImageProperties;
 - (int)_repetitionCount;
 - (float)_frameDuration;
 - (void)_stopAnimation;
@@ -36,27 +38,20 @@ static CFDictionaryRef imageSourceOptions;
     
     [self _invalidateImages];
     
+    [self _invalidateImageProperties];
+    
     if (imageSource)
         CFRelease (imageSource); 
         
     if (animatingRenderers)
         CFRelease (animatingRenderers);
+
+    free (frameDurations);
 }
 
 - (void)dealloc
 {
-    size_t i, num;
-    
-    num = [self numberOfImages];
-    for (i = 0; i < imagePropertiesSize; i++) {
-        CFRelease (imageProperties[i]);
-    }
-    free (imageProperties);
-    
-    free (frameDurations);
-
     [self _commonTermination];
-    
     [super dealloc];
 }
 
@@ -103,6 +98,45 @@ static CFDictionaryRef imageSourceOptions;
     }
 }
 
+- (void)_invalidateImageProperties
+{
+    size_t i;
+    for (i = 0; i < imagePropertiesSize; i++) {
+       if (imageProperties[i])
+           CFRelease (imageProperties[i]);
+    }
+    free (imageProperties);
+    imageProperties = 0;
+    imagePropertiesSize = 0;
+}
+
+- (CGImageRef)_noColorCorrectionImage:(CGImageRef)image withProperties:(CFDictionaryRef)props;
+{
+#if NO_COLOR_CORRECTION
+    CGColorSpaceRef uncorrectedColorSpace = 0;
+    CGImageRef noColorCorrectionImage = 0;
+
+    if (!CFDictionaryGetValue (props, kCGImagePropertyProfileName)) {
+       CFStringRef colorModel = CFDictionaryGetValue (props, kCGImagePropertyColorModel);
+       
+       if (colorModel) {
+           if (CFStringCompare (colorModel, (CFStringRef)@"RGB", 0) == kCFCompareEqualTo)
+               uncorrectedColorSpace = CGColorSpaceCreateDisplayRGB();
+           else if (CFStringCompare (colorModel, (CFStringRef)@"Gray", 0) == kCFCompareEqualTo)
+               uncorrectedColorSpace = CGColorSpaceCreateDisplayGray();
+       }
+       
+       if (uncorrectedColorSpace) {
+           noColorCorrectionImage = CGImageCreateCopyWithColorSpace (image, uncorrectedColorSpace);
+           CFRelease (uncorrectedColorSpace);
+       }
+    }
+    return noColorCorrectionImage;
+#else
+    return 0;
+#endif
+}
+           
 - (CGImageRef)imageAtIndex:(size_t)index
 {
     size_t num = [self numberOfImages];
@@ -146,6 +180,18 @@ static CFDictionaryRef imageSourceOptions;
             if (images[index] == 0)
                 ERROR ("unable to create image at index %d, containerStatus %d, image status %d", (int)index, containerStatus, imageStatus);
         }
+       
+#if NO_COLOR_CORRECTION
+       if (imageStatus >= kCGImageStatusIncomplete) {
+           CGImageRef noColorCorrectionImage = [self _noColorCorrectionImage:images[index]
+                                               withProperties:[self propertiesAtIndex:index]];
+           if (noColorCorrectionImage) {
+               CFRelease (images[index]);
+               images[index] = noColorCorrectionImage;
+           }
+       }
+#endif
+       
         return images[index];
     }
     return 0;
@@ -161,7 +207,7 @@ static CFDictionaryRef imageSourceOptions;
     CFDataRef data = CFDataCreate (NULL, bytes, length);
     CGImageSourceUpdateData (imageSource, data, isComplete);
     CFRelease (data);
-    
+
     // Always returns YES because we can't rely on status.  See 3827851
     //CGImageSourceStatus status = CGImageSourceGetStatus(imageSource);
     //
@@ -170,7 +216,7 @@ static CFDictionaryRef imageSourceOptions;
 }
 
 - (void)drawImageAtIndex:(size_t)index inRect:(CGRect)ir fromRect:(CGRect)fr compositeOperation:(CGCompositeOperation)op context:(CGContextRef)aContext;
-{
+{    
     CGImageRef image = [self imageAtIndex:index];
     
     if (!image)
@@ -178,14 +224,16 @@ static CFDictionaryRef imageSourceOptions;
 
     CGContextSaveGState (aContext);
 
-    float w = CGImageGetWidth(image);
+    //float w = CGImageGetWidth(image);
     float h = CGImageGetHeight(image);
 
     // Is the amount of available bands less than what we need to draw?  If so,
     // clip.
+    BOOL clipping = NO;
     if (h < fr.size.height) {
        fr.size.height = h;
        ir.size.height = h;
+       clipping = YES;
     }
     
     // Flip the coords.
@@ -199,7 +247,10 @@ static CFDictionaryRef imageSourceOptions;
     
     // If we're drawing a sub portion of the image then create
     // a image for the sub portion and draw that.
-    if (fr.size.width != w || fr.size.height != h) {
+    // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
+    if (fr.origin.x != 0 || fr.origin.y != 0 || 
+       fr.size.width != ir.size.width || fr.size.height != fr.size.height ||
+       clipping) {
         image = CGImageCreateWithImageInRect (image, fr);
         if (image) {
             CGContextDrawImage (aContext, ir, image);
@@ -332,13 +383,7 @@ CGPatternCallbacks patternCallbacks = { 0, drawPattern, NULL };
     // Number of images changed!
     if (imagePropertiesSize && num > imagePropertiesSize) {
         // Clear cache.
-        size_t i;
-        for (i = 0; i < imagePropertiesSize; i++) {
-            CFRelease (imageProperties[i]);
-        }
-        free (imageProperties);
-        imageProperties = 0;
-        imagePropertiesSize = 0;
+       [self _invalidateImageProperties];
     }
     
     if (imageProperties == 0 && num) {