我从libpng文档中获取了以下代码: 此外,如果它有任何用途,则此代码位于从基于gtkmm的应用程序调用的类中。
FILE *fp = fopen(path.c_str(), "rb");
if (!fp)
return false;
unsigned char sig[8];
fread(sig, 1, 8, fp);
if (!png_sig_cmp(sig, 0, 8))
return false;
我安装了debuginfo,并从命令行运行gdb。我继续逐步完成代码,看看为什么png_sig_cmp()
函数说我用GIMP创建的png的前8位和我从互联网上下载的一些其他.png文件都没有被PNG。我希望gdb的输出对你来说比对我更有用:
...
_IO_fread (buf=<optimized out>, size=1, count=8, fp=0x848440) at iofread.c:43
43 _IO_acquire_lock (fp);
(gdb)
_IO_acquire_lock_fct (p=<optimized out>) at libioP.h:968
968 if ((fp->_flags & _IO_USER_LOCK) == 0)
(gdb)
969 _IO_funlockfile (fp);
(gdb)
_IO_fread (buf=<optimized out>, size=1, count=8, fp=0x848440) at iofread.c:46
46 return bytes_requested == bytes_read ? count : bytes_read / size;
(gdb)
47 }
(gdb)
PNGFileReader::read_png (this=0x7ca620, path=<optimized out>) at pngfilereader.cpp:46
46 if (!png_sig_cmp(sig, 0, 8))
(gdb) step
png_sig_cmp (sig=0x7fffffffd830 "\211PNG\r\n\032\n\236\330\377\377\377\177", start=0, num_to_check=8) at png.c:122
122 {
(gdb)
124 if (num_to_check > 8)
(gdb)
123 png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
(gdb)
124 if (num_to_check > 8)
(gdb)
126 else if (num_to_check < 1)
(gdb)
127 return (-1);
(gdb)
126 else if (num_to_check < 1)
(gdb)
129 if (start > 7)
(gdb)
130 return (-1);
(gdb)
129 if (start > 7)
(gdb)
132 if (start + num_to_check > 8)
(gdb)
135 return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
(gdb)
__memcmp_sse4_1 () at ../sysdeps/x86_64/multiarch/memcmp-sse4.S:52
52 pxor %xmm0, %xmm0
(gdb)
53 cmp $79, %rdx
(gdb)
54 ja L(79bytesormore)
(gdb)
56 cmp $1, %rdx
(gdb)
57 je L(firstbyte)
(gdb)
59 add %rdx, %rsi
(gdb)
60 add %rdx, %rdi
(gdb)
61 BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4)
(gdb)
803 mov -8(%rdi), %rax
(gdb)
804 mov -8(%rsi), %rcx
(gdb)
805 cmp %rax, %rcx
(gdb)
806 jne L(diffin8bytes)
(gdb)
807 xor %eax, %eax
(gdb)
__memcmp_sse4_1 () at ../sysdeps/x86_64/multiarch/memcmp-sse4.S:808
808 ret
(gdb)
png_sig_cmp (sig=<optimized out>, start=<optimized out>, num_to_check=<optimized out>) at png.c:136
136 }
(gdb)
PNGFileReader::read_png (this=0x7ca620, path=<optimized out>) at pngfilereader.cpp:47
47 return false;
(gdb)
46 if (!png_sig_cmp(sig, 0, 8))
从png_sig_cmp
函数返回的堆栈跟踪是
#0 PNGFileReader::read_png (this=0x7ca620, path=<optimized out>) at pngfilereader.cpp:46
#1 0x0000000000409017 in DrawingArea::zoom (this=0x7c8360, zoom_factor=<optimized out>) at drawingarea.cpp:97
#2 0x00000000004090cd in DrawingArea::on_scroll_event (this=<optimized out>, event=<optimized out>) at drawingarea.cpp:70
#3 0x000000351fd5cb03 in Gtk::Widget_Class::scroll_event_callback (self=0x6df8e0 [gtkmm__GtkDrawingArea], p0=0x7bf4b0) at widget.cc:4474
#4 0x000000351cf52848 in _gtk_marshal_BOOLEAN__BOXED (closure=0x62d640, return_value=0x7fffffffda80, n_param_values=<optimized out>, param_values=0x82da90,
invocation_hint=<optimized out>, marshal_data=<optimized out>) at gtkmarshalers.c:85
#5 0x0000003515a0ea24 in g_closure_invoke (closure=0x62d640, return_value=0x7fffffffda80, n_param_values=2, param_values=0x82da90, invocation_hint=<optimized out>)
at gclosure.c:774
#6 0x0000003515a20b5c in signal_emit_unlocked_R (node=<optimized out>, detail=0, instance=0x6df8e0, emission_return=0x7fffffffdbe0, instance_and_params=0x82da90)
at gsignal.c:3310
#7 0x0000003515a29f13 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=<optimized out>) at gsignal.c:3013
#8 0x0000003515a2a2e2 in g_signal_emit (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3060
#9 0x000000351d07eff9 in gtk_widget_event_internal (widget=0x6df8e0 [gtkmm__GtkDrawingArea], event=0x7bf4b0) at gtkwidget.c:6132
#10 0x000000351cf51fba in gtk_propagate_event (widget=0x6df8e0 [gtkmm__GtkDrawingArea], event=0x7bf4b0) at gtkmain.c:2614
#11 0x000000351cf523bb in gtk_main_do_event (event=0x7bf4b0) at gtkmain.c:1889
#12 0x000000351de47572 in gdk_event_source_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at gdkeventsource.c:360
#13 0x0000003514a44acd in g_main_dispatch (context=0x663aa0) at gmain.c:2441
#14 g_main_context_dispatch (context=0x663aa0) at gmain.c:3011
#15 0x0000003514a452c8 in g_main_context_iterate (context=0x663aa0, block=<optimized out>, dispatch=1, self=<optimized out>) at gmain.c:3089
#16 0x0000003514a45815 in g_main_loop_run (loop=0x8564c0) at gmain.c:3297
#17 0x000000351cf517fd in gtk_main () at gtkmain.c:1362
#18 0x000000351fcfd026 in Gtk::Main::run (window=...) at main.cc:384
#19 0x00000000004075f0 in main (argc=1, argv=0x7fffffffe168) at main.cpp:10
答案 0 :(得分:1)
问题似乎是检查png_sig_cmp
的返回值。看一下文档,它似乎遵循memcmp
返回样式,换句话说,对于一个好的头,返回0,对于不匹配,返回非零。