iOS:CGImageCreateWith [PNG或JPEG] DataProvider导致分段错误 [英] iOS: CGImageCreateWith[PNG or JPEG]DataProvider causes segmentation fault

查看:790
本文介绍了iOS:CGImageCreateWith [PNG或JPEG] DataProvider导致分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临一个奇怪的问题。我正在使用libzbar开发一个iOS命令行条形码扫描器实用程序(是的,这是用于越狱设备)。一切顺利,除非我正在尝试使用 CGImageCreateWithPNGDataProvider() CGImageCreateWithJPEGDataProvider()方法来获取<来自文件的code> CGImageRef - 因为这两个函数在我的5.1.1 iPad上抛出一个段错误。问题不在我的自定义类 ZBarScanner 中,因为如果我使用UIImage获取图像数据,请使用类似

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 CGImageCreateWithPNGDataProvider() or CGImageCreateWithJPEGDataProvider() methods to obtain a CGImageRef from a file - because these two functions throw a segfault on my 5.1.1 iPad. The problem is not in my custom class, ZBarScanner, because if I use an UIImage to obtain the image data, using something like

UIImage *uiImage = [UIImage imageWithContentsOfFile:fname];
CGImageRef image = uiImage.CGImage;

然后它工作正常并打印存储在条形码中的数据。此外,PNG和JPEG图像格式正确 - 我可以使用设备本身的文件浏览器查看它们,我也尝试了其他几个图像。我甚至试图省略所有 CFRelease()函数调用和发布消息,以避免有悬空指针。这是我的代码:

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 CFRelease() function calls and release messages in order to avoid having dangling pointers. Here's my 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;
}

如果我在调试器中运行它(为清晰起见,GDB和NSLog杂乱删除) :

If I run it in the debugger (GDB and NSLog clutter removed for clarity):

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)

所以即使是回溯也没有显示任何明显错误/有用......似乎某些东西某处。我甚至怀疑由于我的工具链是一个非官方的4.0版本,这些功能可能在iOS 5.1.1中不可用,所以构建成功为 CGImageCreateWith [...] DataProvider 符号在开发 sysroot中,但在iOS'实际动态库中没有,但如果是这种情况,我NSLogged的函数指针将是 NULL ,对吗?但是,NS和CG对象以及函数似乎都不是NULL - 我传递给CGImage构造函数的唯一NULL是 decodeArray 参数,但它在Apple的明确提到文档,它可以是NULL ...(更新:我尝试传递一个有效的非NULL数组来查明文档是否错误,但我仍然遇到同样的错误。)

So even the backtrace doesn't show anything obviously wrong/helpful... It seems though that something is NULL somewhere. 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 CGImageCreateWith[...]DataProvider symbols are inside the development sysroot but not among iOS' actual dynamic libraries, but if this was the case, the function pointer I NSLogged out would be NULL, 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 decodeArray parameter, but it's explicitly mentioned in Apple's documentation that it can be NULL... (Update: I tried passing a valid non-NULL array to find out if the documentation is wrong, but I still got the same error).

请问关于此次崩溃的任何指示(双关语)?我在这里想念的是什么?到目前为止我发现的所有教程和参考建议使用CGDataProvider和CGImage就像这样。

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.

推荐答案

当使用文件名时,样本Apple文档中的代码使用了您在评论中提到的尝试的组合,加上值 kCGRenderingIntentPerceptual 而不是默认值:

when using a filename, the sample code from the apple documentation uses a combination of what you had mentioned trying in your comments, plus the value kCGRenderingIntentPerceptual rather than the default:

    CGDataProviderRef pngDP = CGDataProviderCreateWithFilename([filePath fileSystemRepresentation]);
    if (pngDP) {
        CGImageRef img = CGImageCreateWithPNGDataProvider(pngDP, NULL, true, kCGRenderingIntentPerceptual); // true for interpolate, false for not-interpolate

这样做可以防止你不得不保留数据本身在您的程序中,可能会阻止您看到的段错误。

doing this should keep you from having to keep the data itself in your program, and may prevent the segfault you're seeing.

(至少可以获取并尝试官方发现的CoreTextPageViewer示例代码iOS文档,构建该项目,并试图弄清楚你在做什么不同。)

(at the very least, perhaps get and try the sample code for CoreTextPageViewer found in the official iOS documentation, build that project, and try to figure out how what you're doing differs.)

这篇关于iOS:CGImageCreateWith [PNG或JPEG] DataProvider导致分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆