title: iOS: CGImageCreateWith[PNG or JPEG]DataProvider causes segmentation fault
body: <p>I'm facing a weird problem. I'm developing an iOS command line barcode scanner utility using libzbar (yes, this is for jailbroken devices). All goes fine except when I'm trying to use the <code>CGImageCreateWithPNGDataProvider()</code> or <code>CGImageCreateWithJPEGDataProvider()</code> methods to obtain a <code>CGImageRef</code> from a file - because these two functions throw a segfault on my 5.1.1 iPad. The problem is not in my custom class, <code>ZBarScanner</code>, because if I use an UIImage to obtain the image data, using something like</p>
  
  <pre><code>UIImage *uiImage = [UIImage imageWithContentsOfFile:fname];
  CGImageRef image = uiImage.CGImage;
  </code></pre>
  
  <p>then it works fine and prints the data stored in the barcode. Also, the PNG and JPEG images are well-formatted - I can view them using a file browser on the device itself and I tried several other images as well. I even tried to omit all the <code>CFRelease()</code> function calls and <code>release</code> messages in order to avoid having dangling pointers. Here's my code:</p>
  
  <pre><code>#define LOG() NSLog(@"Reached line %d", __LINE__)
  
  int main(int argc, char **argv)
  {
      if (argc != 2)
              return 1;
  
      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  
      LOG(); // line 21
  
      NSString *fname = [[NSString stringWithUTF8String:argv[1]] retain]; // added an extra retain just in case
  
      LOG(); // line 25
  
      CFDataRef data = (CFDataRef)[NSData dataWithContentsOfFile:fname];
      CGDataProviderRef dProv = CGDataProviderCreateWithCFData(data);
      // I also tried using
      // dProv = CGDataProviderCreateWithFilename(argv[1]);
      // that made no difference either. The data and data provider are
      // valid, but the CGImage constructors always segfault.
      if (dProv == NULL) {
          fprintf(stderr, "Invalid CGDataProvider\n");
          abort();
      }
  
      LOG(); // line 34
  
      CGImageRef image = NULL;
  
      if ([[fname pathExtension] isEqualToString:@"png"]) {
          LOG(); // line 39
          NSLog(@"Function pointer: %p", CGImageCreateWithPNGDataProvider);
          image = CGImageCreateWithPNGDataProvider(dProv, NULL, false, kCGRenderingIntentDefault); // This function segfaults, or...
          LOG();
      } else if ([[fname pathExtension] isEqualToString:@"jpg"]
          || [[fname pathExtension] isEqualToString:@"jpeg"]) {
          LOG();
          image = CGImageCreateWithJPEGDataProvider(dProv, NULL, true, kCGRenderingIntentDefault); // ... or this one.
          LOG();
      } else {
          fprintf(stderr, "File '%s' is neither a PNG nor a JPEG file!\n", argv[1]);
          LOG();
          abort();
      }
  
      LOG();
      // CFRelease(dProv);
      LOG();
      ZBarScanner *scanner = [ZBarScanner zbarScannerWithCGImage:image];
      // CFRelease(image);
      LOG();
      NSArray *arr = [scanner scan];
      NSLog(@"The result of the scanning is:\n%@", arr);
      LOG();
      [pool drain];
  
      return 0;
  }
  </code></pre>
  
  <p>If I run it in the debugger (GDB and NSLog clutter removed for clarity):</p>
  
  <pre><code>gdb ./scanner
  (gdb) run ./barcode1.png
  Reached line 21
  Reached line 25
  Reached line 34
  Reached line 39
  Function pointer: 0x37c5b535
  
  Program received signal EXC_BAD_ACCESS, Could not access memory.
  Reason: KERN_INVALID_ADDRESS at address: 0x00000000
  0x00000000 in ?? ()
  (gdb) backtrace
  #0 0x00000000 in ?? ()
  (gdb)
  </code></pre>
  
  <p>So even the backtrace doesn't show anything obviously wrong/helpful... It seems though that <em>something</em> is NULL <em>somewhere</em>. I even suspected that due to my toolchain being an unofficial 4.0-based build, these functions might not be available in iOS 5.1.1, so the build succeeds as the <code>CGImageCreateWith[...]DataProvider</code> symbols are inside the <strong>development</strong> sysroot but not among iOS' <strong>actual</strong> dynamic libraries, but if this was the case, the function pointer I NSLogged out would be <code>NULL</code>, right? However, neither of the NS and CG objects nor the functions seem to be NULL - the only NULL I pass to the CGImage constructors is a <code>decodeArray</code> parameter, but it's explicitly mentioned in Apple's documentation that it can be NULL... (<em>Update</em>: I tried passing a valid non-NULL array to find out if the documentation is wrong, but I still got the same error).</p>
  
  <p>Could you please give me any pointers (pun intended) about this crash? What am I missing here? All tutorials and references I have found so far suggest using CGDataProvider and CGImage just like this.</p>