title: CGPDF - Saving images with FlateDecode Filter
body: <p>I'm writing a PDF parser for work, and we're using Core Graphics to read in all of the data with callbacks and then writing it out with Lib Haru because our client needs to write out "real" annotations and CG can't do it.</p>
  
  <p>Well, I've gotten to the point where I am getting images (and saving them out to a file to make sure I'm doing it right before I start to draw them) and I've run into an issue. I'm getting all of the Image XObjects out of the Resource dictionary and then attempting to save them out with this code</p>
  
  <pre><code>NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *documentsDir = [paths objectAtIndex:0];                
  
  NSData *imageFileData = (NSData *)CGPDFStreamCopyData(objectStream, CGPDFDataFormatRaw);
  
  NSString *fileName = [NSString stringWithFormat:@"%@/%s.png", documentsDir, name];
  [imageFileData writeToFile:fileName atomically:YES];
  </code></pre>
  
  <p>where the objectStream is using the CGPDFDictionaryGetStream to extract the XObject. Well, it works fine when the Filter is "DCTDecode", but whenever the Filter is "FlateDecode", the image that is saved is corrupt and won't open.</p>
  
  <p>I read in <a href="https://stackoverflow.com/questions/4584540/is-there-any-pdf-parser-written-in-objective-c-or-c" title="this post">this post</a> that CGPDFStreamCopyData can decode text with FlateDecode (all the way to the bottom of the post in the comments), but there are only 3 data formats in the CGPDFDataFormats, and none of them work.</p>
  
  <p>I believe I'm also having issues with text that is encoded with FlatDecode. Does anyone have any suggestions on how to go about decoding this? Surely CGPDF has something that handles this since it appears in almost every pdf that I've tried to open (though I haven't been able to locate it).</p>
  
  <p><strong>Edit:</strong> I read in a few places that I could decompress it using zlib, so I tried this code that I was able to find about how to do that:</p>
  
  <pre><code>            NSData* uncompressedImageData;
              if ([imageFileData length] == 0) 
                  uncompressedImageData = imageFileData;
              else
              {                
                  z_stream strm;
                  strm.zalloc = Z_NULL; 
                  strm.zfree = Z_NULL; 
                  strm.opaque = Z_NULL; 
                  strm.total_out = 0; 
                  strm.next_in=(Bytef*)[imageFileData bytes]; 
                  strm.avail_in = [imageFileData length];
  
                  // Compresssion Levels: // Z_NO_COMPRESSION // Z_BEST_SPEED // Z_BEST_COMPRESSION // Z_DEFAULT_COMPRESSION
                  if (deflateInit(&amp;strm, Z_DEFAULT_COMPRESSION) != Z_OK) 
                      uncompressedImageData = nil;
  
                  NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chuncks for expansion
                  do 
                  {
                      if (strm.total_out &gt;= [compressed length]) 
                          [compressed increaseLengthBy: 16384];
  
                      strm.next_out = [compressed mutableBytes] + strm.total_out; strm.avail_out = [compressed length] - strm.total_out;
                      deflate(&amp;strm, Z_FINISH);
                  } 
                  while (strm.avail_out == 0);
  
                  deflateEnd(&amp;strm);
                  [compressed setLength: strm.total_out]; 
  
                  uncompressedImageData = [NSData dataWithData: compressed]; 
              }
  
              if(uncompressedImageData != nil)
                  [uncompressedImageData writeToFile:fileName atomically:YES];
  </code></pre>
  
  <p>The code didn't throw any exceptions when I ran it, but the resulting images were still unreadable.</p>