title: CGImage rotation method memory leak on iOS
body: <p>I have this code to rotate CGImage:</p>
  
  <pre><code>- (CGImageRef)rotateCGImageRef:(CGImageRef)imageRef toOrientation:(UIImageOrientation)orientation
  {
      CGRect             bnds = CGRectZero;
      CGImageRef         copy = nil;
      CGContextRef       ctxt = nil;
      CGRect             rect = CGRectZero;
      CGAffineTransform  tran = CGAffineTransformIdentity;
  
      @autoreleasepool {
          bnds.size = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); //self.size;
          rect.size = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); //self.size;
  
          switch (orientation)
          {
              case UIImageOrientationUp:
                  return imageRef;
  
              case UIImageOrientationUpMirrored:
                  tran = CGAffineTransformMakeTranslation(rect.size.width, 0.0);
                  tran = CGAffineTransformScale(tran, -1.0, 1.0);
                  break;
  
              case UIImageOrientationDown:
                  tran = CGAffineTransformMakeTranslation(rect.size.width, rect.size.height);
                  tran = CGAffineTransformRotate(tran, degreesToRadians(180.0));
                  break;
  
              case UIImageOrientationDownMirrored:
                  tran = CGAffineTransformMakeTranslation(0.0, rect.size.height);
                  tran = CGAffineTransformScale(tran, 1.0, -1.0);
                  break;
  
              case UIImageOrientationLeft:
                  bnds.size = swapWidthAndHeight(bnds.size);
                  tran = CGAffineTransformMakeTranslation(0.0, rect.size.width);
                  tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0));
                  break;
  
              case UIImageOrientationLeftMirrored:
                  bnds.size = swapWidthAndHeight(bnds.size);
                  tran = CGAffineTransformMakeTranslation(rect.size.height, rect.size.width);
                  tran = CGAffineTransformScale(tran, -1.0, 1.0);
                  tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0));
                  break;
  
              case UIImageOrientationRight:
                  bnds.size = swapWidthAndHeight(bnds.size);
                  tran = CGAffineTransformMakeTranslation(rect.size.height, 0.0);
                  tran = CGAffineTransformRotate(tran, degreesToRadians(90.0));
                  break;
  
              case UIImageOrientationRightMirrored:
                  bnds.size = swapWidthAndHeight(bnds.size);
                  tran = CGAffineTransformMakeScale(-1.0, 1.0);
                  tran = CGAffineTransformRotate(tran, degreesToRadians(90.0));
                  break;
  
              default:
                  // orientation value supplied is invalid
                  assert(false);
                  return nil;
          }
  
          UIGraphicsBeginImageContext(bnds.size);
          ctxt = UIGraphicsGetCurrentContext();
  
          switch (orientation)
          {
              case UIImageOrientationLeft:
              case UIImageOrientationLeftMirrored:
              case UIImageOrientationRight:
              case UIImageOrientationRightMirrored:
                  CGContextScaleCTM(ctxt, -1.0, 1.0);
                  CGContextTranslateCTM(ctxt, -rect.size.height, 0.0);
                  break;
  
              default:
                  CGContextScaleCTM(ctxt, 1.0, -1.0);
                  CGContextTranslateCTM(ctxt, 0.0, -rect.size.height);
                  break;
          }
  
          CGContextConcatCTM(ctxt, tran);
          CGContextDrawImage(ctxt, rect, imageRef);
  
          //copy = UIGraphicsGetImageFromCurrentImageContext();
          copy = CGBitmapContextCreateImage(ctxt);
          UIGraphicsEndImageContext();
      }
      return copy;
  }
  </code></pre>
  
  <p>But Analyzer says it has leak:
  <img src="https://i.stack.imgur.com/oIDUo.png" alt="memory leak"></p>
  
  <p>I cannot release copy object cos I method is returning it.</p>
  
  <p>What is actually leaking?</p>
  
  <p><strong>EDIT:</strong>
  Here is the final code converted to C function:</p>
  
  <pre><code>CGImageRef CreateRotatedImage(CGImageRef imageRef, UIImageOrientation orientation)
  {
      CGRect             bnds = CGRectZero;
      CGImageRef         copy = nil;
      CGContextRef       ctxt = nil;
      CGRect             rect = CGRectZero;
      CGAffineTransform  tran = CGAffineTransformIdentity;
  
      bnds.size = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); //self.size;
      rect.size = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); //self.size;
  
      switch (orientation)
      {
          case UIImageOrientationUp:
              return imageRef;
  
          case UIImageOrientationUpMirrored:
              tran = CGAffineTransformMakeTranslation(rect.size.width, 0.0);
              tran = CGAffineTransformScale(tran, -1.0, 1.0);
              break;
  
          case UIImageOrientationDown:
              tran = CGAffineTransformMakeTranslation(rect.size.width, rect.size.height);
              tran = CGAffineTransformRotate(tran, degreesToRadians(180.0));
              break;
  
          case UIImageOrientationDownMirrored:
              tran = CGAffineTransformMakeTranslation(0.0, rect.size.height);
              tran = CGAffineTransformScale(tran, 1.0, -1.0);
              break;
  
          case UIImageOrientationLeft:
              bnds.size = swapWidthAndHeight(bnds.size);
              tran = CGAffineTransformMakeTranslation(0.0, rect.size.width);
              tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0));
              break;
  
          case UIImageOrientationLeftMirrored:
              bnds.size = swapWidthAndHeight(bnds.size);
              tran = CGAffineTransformMakeTranslation(rect.size.height, rect.size.width);
              tran = CGAffineTransformScale(tran, -1.0, 1.0);
              tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0));
              break;
  
          case UIImageOrientationRight:
              bnds.size = swapWidthAndHeight(bnds.size);
              tran = CGAffineTransformMakeTranslation(rect.size.height, 0.0);
              tran = CGAffineTransformRotate(tran, degreesToRadians(90.0));
              break;
  
          case UIImageOrientationRightMirrored:
              bnds.size = swapWidthAndHeight(bnds.size);
              tran = CGAffineTransformMakeScale(-1.0, 1.0);
              tran = CGAffineTransformRotate(tran, degreesToRadians(90.0));
              break;
  
          default:
              // orientation value supplied is invalid
              assert(false);
              return nil;
      }
  
      UIGraphicsBeginImageContext(bnds.size);
      ctxt = UIGraphicsGetCurrentContext();
  
      switch (orientation)
      {
          case UIImageOrientationLeft:
          case UIImageOrientationLeftMirrored:
          case UIImageOrientationRight:
          case UIImageOrientationRightMirrored:
              CGContextScaleCTM(ctxt, -1.0, 1.0);
              CGContextTranslateCTM(ctxt, -rect.size.height, 0.0);
              break;
  
          default:
              CGContextScaleCTM(ctxt, 1.0, -1.0);
              CGContextTranslateCTM(ctxt, 0.0, -rect.size.height);
              break;
      }
  
      CGContextConcatCTM(ctxt, tran);
      CGContextDrawImage(ctxt, rect, imageRef);
  
      //copy = UIGraphicsGetImageFromCurrentImageContext();
      copy = CGBitmapContextCreateImage(ctxt);
      UIGraphicsEndImageContext();
      return copy;
  }
  </code></pre>
  
  <p>Call to this C function:</p>
  
  <pre><code>imageRef = CreateRotatedImage(imageRef, UIImageOrientationRight);
  </code></pre>