I successfully compiled opencv_example (which is VLC video filter plugin from vlc/modules/video_filter). But it doesn't want to work on me.
I run vlc as the following:
XXX#XXX:/opt/vlc-2.0.1-td/bin$ vlc --video-filter opencv_example
VLC runs, I open the video file, it opens well (I see frames). But then the debug always answered me with:
[0x7f3bec792b78] main filter error: corrupt module: /usr/local/lib/vlc/plugins/video_filter/libopencv_example_plugin.so
[0x7f3bec1728f8] main video output error: Failed to create video filter2 'opencv_example'
[0x7f3bec1728f8] main video output error: Failed to add filter 'opencv_example'
[0x7f3bee4b1a88] main filter error: corrupt module: /usr/local/lib/vlc/plugins/video_filter/libopencv_example_plugin.so
[0x7f3bec1728f8] main video output error: Failed to create video filter2 'opencv_example'
[0x7f3bec1728f8] main video output error: Failed to add filter 'opencv_example'
I found out that it may be linking error, since when I run ldd util, I can't see the reference to any opencv library among the libraries, used by libopencv_example_plugin.so:
XXX#XXX:/usr/local/lib/vlc/plugins/video_filter$ ldd libopencv_example_plugin.so
linux-vdso.so.1 => (0x00007fff947ff000)
libvlccore.so.5 => /usr/local/lib/libvlccore.so.5 (0x00007f9c1b92c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9c1b56c000)
libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f9c1b327000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f9c1b11f000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9c1af02000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9c1acfd000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9c1aa01000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9c1be31000)
So. The question is listed above: how can I make opencv_example work?
I'm working on Ubuntu 12.04 with VLC 2.0.1, OpenCV 2.4.9
Thanks in advance for everyone!
Finally dealed with that die hard. The problem of running opencv_example is complex, so there are two steps to solve it:
1 Link necessary OpenCV libraries
My initial thought was true: failure in creating VLC video filter is caused by unlinked OpenCV libraries.
To link them open configure.ac for writing. Then find the following line:
PKG_ENABLE_MODULES_VLC([OPENCV], [opencv_example opencv_wrapper], [opencv], (OpenCV (computer vision) filter), [off])
This exact line tells VLC NOT to link OpenCV to opencv_example and opencv_wrapper. So change it and add some more lines to check the availability of CV-functions:
PKG_ENABLE_MODULES_VLC([OPENCV], [opencv_example opencv_wrapper], [opencv], (OpenCV (computer vision) filter), [on])
AC_MSG_CHECKING([opencv libs for opencv_example & opencv_wrapper])
AC_CHECK_LIB(opencv_objdetect, cvHaarDetectObjects,
[
VLC_ADD_PLUGIN([opencv_wrapper opencv_example])
VLC_ADD_CFLAGS([opencv_wrapper opencv_example], [$OPENCV_CFLAGS])
VLC_ADD_LIBS([opencv_wrapper opencv_example],[-lopencv_core -lopencv_objdetect])
AC_MSG_RESULT([opencv libs added, cvHaarDetectObjects is ok])
],
AC_MSG_ERROR([opencv libs for opencv_example & opencv_wrapper cannot be added!]))
Save this file, go back to VLC directory and do the following operations:
autoconf
./configure
make
make install
When running ./configure, among the other information your terminal should show:
checking opencv libs for opencv_example & opencv_wrapper...
checking for cvHaarDetectObjects in -lopencv_objdetect... yes
This is a good sing means that OpenCV is installed and VLC is ready to link it to our plugins.
After installing everything (make install) check linkage by running ldd utility in /usr/local/lib/vlc/plugins/video_filter directory (or whereever your VLC-plugins are installed):
XXX#XXX:/usr/local/lib/vlc/plugins/video_filter# ldd libopencv_example_plugin.so
linux-vdso.so.1 => (0x00007fff549cd000)
libvlccore.so.5 => /usr/local/lib/libvlccore.so.5 (0x00007f036aa2a000)
libopencv_core.so.2.4 => /usr/local/lib/libopencv_core.so.2.4 (0x00007f036a5e8000)
libopencv_objdetect.so.2.4 => /usr/local/lib/libopencv_objdetect.so.2.4 (0x00007f036a367000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0369fa7000)
libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f0369d63000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f0369b5a000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f036993d000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f0369739000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f036943c000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f0369225000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0368f25000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0368d0e000)
libopencv_imgproc.so.2.4 => /usr/local/lib/libopencv_imgproc.so.2.4 (0x00007f036884c000)
libopencv_highgui.so.2.4 => /usr/local/lib/libopencv_highgui.so.2.4 (0x00007f03684ae000)
/lib64/ld-linux-x86-64.so.2 (0x00007f036af2f000)
libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007f036825d000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f0368035000)
libtiff.so.4 => /usr/lib/x86_64-linux-gnu/libtiff.so.4 (0x00007f0367dd0000)
libgtk-x11-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 (0x00007f0367796000)
libgdk-x11-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0 (0x00007f03674e4000)
libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f0367294000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f0366f9f000)
libdc1394.so.22 => /usr/lib/x86_64-linux-gnu/libdc1394.so.22 (0x00007f0366d2c000)
libv4l1.so.0 => /usr/lib/x86_64-linux-gnu/libv4l1.so.0 (0x00007f0366b25000)
libavcodec.so.53 => /usr/lib/x86_64-linux-gnu/libavcodec.so.53 (0x00007f0365d15000)
libavformat.so.53 => /usr/lib/x86_64-linux-gnu/libavformat.so.53 (0x00007f0365a15000)
libavutil.so.51 => /usr/lib/x86_64-linux-gnu/libavutil.so.51 (0x00007f03657f4000)
libswscale.so.2 => /usr/lib/x86_64-linux-gnu/libswscale.so.2 (0x00007f03655ae000)
libpangocairo-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 (0x00007f03653a1000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f036506c000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f0364e66000)
libatk-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libatk-1.0.so.0 (0x00007f0364c43000)
libcairo.so.2 => /usr/lib/x86_64-linux-gnu/libcairo.so.2 (0x00007f0364985000)
libgdk_pixbuf-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0 (0x00007f0364765000)
libgio-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 (0x00007f0364415000)
libpangoft2-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 (0x00007f03641eb000)
libpango-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 (0x00007f0363fa2000)
libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f0363d6b000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f0363b5a000)
libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f0363950000)
libXinerama.so.1 => /usr/lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007f036374c000)
libXi.so.6 => /usr/lib/x86_64-linux-gnu/libXi.so.6 (0x00007f036353d000)
libXrandr.so.2 => /usr/lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f0363335000)
libXcursor.so.1 => /usr/lib/x86_64-linux-gnu/libXcursor.so.1 (0x00007f036312a000)
libXcomposite.so.1 => /usr/lib/x86_64-linux-gnu/libXcomposite.so.1 (0x00007f0362f27000)
libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f0362d24000)
libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f0362b1b000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f03628de000)
libraw1394.so.11 => /usr/lib/x86_64-linux-gnu/libraw1394.so.11 (0x00007f03626ce000)
libusb-1.0.so.0 => /lib/x86_64-linux-gnu/libusb-1.0.so.0 (0x00007f03624bf000)
libv4l2.so.0 => /usr/lib/x86_64-linux-gnu/libv4l2.so.0 (0x00007f03622b3000)
libvpx.so.1 => /usr/lib/libvpx.so.1 (0x00007f036200d000)
libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f0361b3e000)
libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007f0361912000)
libtheoraenc.so.1 => /usr/lib/x86_64-linux-gnu/libtheoraenc.so.1 (0x00007f03616d4000)
libtheoradec.so.1 => /usr/lib/x86_64-linux-gnu/libtheoradec.so.1 (0x00007f03614b9000)
libspeex.so.1 => /usr/lib/x86_64-linux-gnu/libspeex.so.1 (0x00007f03612a0000)
libschroedinger-1.0.so.0 => /usr/lib/libschroedinger-1.0.so.0 (0x00007f0360fec000)
libgsm.so.1 => /usr/lib/libgsm.so.1 (0x00007f0360dde000)
libva.so.1 => /usr/lib/x86_64-linux-gnu/libva.so.1 (0x00007f0360bc8000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f03609b7000)
libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f036071b000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f03604fc000)
libpixman-1.so.0 => /usr/lib/x86_64-linux-gnu/libpixman-1.so.0 (0x00007f0360275000)
libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f0360072000)
libxcb-render.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-render.so.0 (0x00007f035fe67000)
libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f035fc63000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f035fa43000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f035f827000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f035f5fc000)
libv4lconvert.so.0 => /usr/lib/x86_64-linux-gnu/libv4lconvert.so.0 (0x00007f035f387000)
libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007f035f180000)
liborc-0.4.so.0 => /usr/lib/x86_64-linux-gnu/liborc-0.4.so.0 (0x00007f035ef04000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f035ed01000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f035eafb000)
See, the amount of linked libraries increased severalfold.
Step one is done. You can check the loading of opencv_example by running your VLC. But rightly then you may face another issue:
...
[0x7f2d741728f8] main video output debug: Adding 'opencv_example' as interactive
[0x7f2d747f7a68] main filter debug: looking for video filter2 module: 1 candidate
[0x7f2d747f7a68] main filter debug: using video filter2 module "opencv_example"
[0x7f2d747f7a68] main filter debug: TIMER module_need() : 149.351 ms - Total 149.351 ms / 1 intvls (Avg 149.351 ms)
[0x7f2d741728f8] main video output debug: Filter 'opencv_example' (0x7f2d747f7a68) appended to chain
[0x7f2d74173cb8] main spu text debug: removing module "freetype"
[0x7f2d74173cb8] main spu text debug: looking for text renderer module: 3 candidates
[0x7f2d74173cb8] freetype spu text debug: Building font databases.
[0x7f2d74173cb8] freetype spu text debug: Took 33 microseconds
[0x7f2d74173cb8] freetype spu text debug: Using Serif Bold as font from file /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf
[0x7f2d74173cb8] freetype spu text debug: using fontsize: 2
[0x7f2d74173cb8] main spu text debug: using text renderer module "freetype"
[0x7f2d74173cb8] main spu text debug: TIMER module_need() : 5.776 ms - Total 5.776 ms / 1 intvls (Avg 5.776 ms)
[0x7f2d8c00d018] main decoder debug: End of video preroll
[0x7f2d8c00d018] main decoder debug: Received first picture
Segmentation fault (core dumped)
2 Change the opencv_example source code
So, as I found out, the error is hidden in converting image from picture_t (VLC structure for storing image) to IplImage (OpenCV type for image):
//(hack) cast the picture_t to array of IplImage*
p_img = (IplImage**) p_pic->p[0].p_pixels;
Just change this convertion a little bit to make everything work well. Here is the full code for Filter method from my modified opencv_example.c:
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{
IplImage* p_img;
int i_planes = 0;
CvPoint pt1, pt2;
int i, scale = 1;
filter_sys_t *p_sys = p_filter->p_sys;
if ((!p_pic))
{
msg_Err( p_filter, "no image array" );
return NULL;
}
i_planes = p_pic->i_planes;
if (i_planes<1)
{
msg_Err( p_filter, "no image planes" );
return NULL;
}
if ((p_pic->format.i_chroma != VLC_CODEC_I420))
{
msg_Err( p_filter, "wrong chroma - use I420" );
return NULL;
}
//picture_t to IplImage without segmentation fault
p_img = cvCreateImageHeader( cvSize( p_pic->p[0].i_pitch, p_pic->p[0].i_visible_lines ),
IPL_DEPTH_8U, 1 );
cvSetData( p_img, p_pic->p[0].p_pixels, p_pic->p[0].i_pitch );
//perform face detection
cvClearMemStorage(p_sys->p_storage);
if( p_sys->p_cascade )
{
//we should make some of these params config variables
CvSeq *faces = cvHaarDetectObjects( p_img, p_sys->p_cascade, p_sys->p_storage,
1.15, 5, CV_HAAR_DO_CANNY_PRUNING,
cvSize(0, 0), cvSize(20, 20) );
//create the video_filter_region_info_t struct
if (faces && (faces->total > 0))
{
msg_Dbg( p_filter, "Found %d face(s)", faces->total );
free( p_sys->event_info.p_region );
p_sys->event_info.p_region = (video_filter_region_info_t*)
calloc( faces->total, sizeof(video_filter_region_info_t));
if( !p_sys->event_info.p_region )
return NULL;
p_sys->event_info.i_region_size = faces->total;
}
//populate the video_filter_region_info_t struct
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect *r = (CvRect*)cvGetSeqElem( faces, i );
pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;
cvRectangle( p_img, pt1, pt2, CV_RGB(0,0,0), 3, 8, 0 );
*(CvRect*)(&(p_sys->event_info.p_region[i])) = *r;
p_sys->event_info.p_region[i].i_id = p_sys->i_id++;
p_sys->event_info.p_region[i].p_description = "Face Detected";
}
if (faces && (faces->total > 0)) //raise the video filter event
var_TriggerCallback( p_filter->p_libvlc, VIDEO_FILTER_EVENT_VARIABLE );
}
else
msg_Err( p_filter, "No cascade - is opencv-haarcascade-file valid?" );
//IplImage to picture_t without segmentation fault
cvGetRawData( p_img, (uchar**)&p_pic->p[0].p_pixels, NULL, NULL );
return p_pic;
}
VLC should work well, as well as opencv_example filter. Please, let me know if you'll have any other issues connected to the topic of VLC+OpenCV
#Anton good solution, what about timing i.e if the function in the filter need quite a time to finish > 500ms will that effect the framerate of the playbck !!
I have this function inside the main.c file which create a simple dialog made of check boxes and entries:
void compute_sha2 (GtkWidget *, struct hashWidget_t *);
void compute_sha3 (GtkWidget *, struct hashWidget_t *);
void compute_md5 (struct hashWidget_t *);
void compute_sha1 (struct hashWidget_t *);
void compute_gost94 (struct hashWidget_t *);
void compute_whirlpool (struct hashWidget_t *);
static void
compute_hash ( GtkWidget *fileDialog,
GtkWidget *mainwin,
const gchar *filename)
{
gtk_widget_hide (GTK_WIDGET (fileDialog));
struct hashWidget_t HashWidget;
gsize lenFilename = g_utf8_strlen (filename, -1);
HashWidget.filename = g_malloc (lenFilename + 1);
if (HashWidget.filename == NULL)
{
g_printerr ("Error during memory allocation\n");
return;
}
g_utf8_strncpy (HashWidget.filename, filename, lenFilename);
HashWidget.filename[lenFilename] = '\0';
gint i, result;
const gchar *label[] = {"MD5", "SHA-1", "SHA-256", "SHA3-256", "SHA512", "SHA3-512", "WHIRLPOOL", "GOST94"};
GtkWidget *contentArea, *grid, *dialog;
GtkDialogFlags flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
PangoFontDescription *newFont = pango_font_description_new ();
pango_font_description_set_family (newFont, "monospace");
dialog = gtk_dialog_new_with_buttons ("Select Hash",
GTK_WINDOW (mainwin),
flags,
_("Cancel"), GTK_RESPONSE_REJECT,
NULL);
gtk_widget_set_size_request (dialog, 250, 150);
contentArea = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
for (i = 0; i < NUM_OF_HASH; i++)
{
HashWidget.hashCheck[i] = gtk_check_button_new_with_label (label[i]);
HashWidget.hashEntry[i] = gtk_entry_new ();
gtk_editable_set_editable (GTK_EDITABLE (HashWidget.hashEntry[i]), FALSE);
gtk_widget_override_font (GTK_WIDGET (HashWidget.hashEntry[i]), newFont);
}
pango_font_description_free (newFont);
grid = gtk_grid_new ();
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_set_row_spacing (GTK_GRID (grid), 5);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashCheck[0], 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashEntry[0], 2, 0, 6, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashCheck[1], 0, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashEntry[1], 2, 1, 6, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashCheck[2], 0, 2, 1, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashEntry[2], 2, 2, 6, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashCheck[3], 0, 3, 1, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashEntry[3], 2, 3, 6, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashCheck[4], 0, 4, 1, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashEntry[4], 2, 4, 6, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashCheck[5], 0, 5, 1, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashEntry[5], 2, 5, 6, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashCheck[6], 0, 6, 1, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashEntry[6], 2, 6, 6, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashCheck[7], 0, 7, 1, 1);
gtk_grid_attach (GTK_GRID (grid), HashWidget.hashEntry[7], 2, 7, 6, 1);
gtk_container_add (GTK_CONTAINER (contentArea), grid);
gtk_widget_show_all (dialog);
gtk_widget_set_name (GTK_WIDGET (HashWidget.hashCheck[2]), "BtSha256");
gtk_widget_set_name (GTK_WIDGET (HashWidget.hashCheck[3]), "BtSha3_256");
gtk_widget_set_name (GTK_WIDGET (HashWidget.hashCheck[4]), "BtSha512");
gtk_widget_set_name (GTK_WIDGET (HashWidget.hashCheck[5]), "BtSha3_512");
g_signal_connect_swapped (HashWidget.hashCheck[0], "clicked", G_CALLBACK (compute_md5), &HashWidget);
g_signal_connect_swapped (HashWidget.hashCheck[1], "clicked", G_CALLBACK (compute_sha1), &HashWidget);
g_signal_connect (HashWidget.hashCheck[2], "clicked", G_CALLBACK (compute_sha2), &HashWidget);
g_signal_connect (HashWidget.hashCheck[3], "clicked", G_CALLBACK (compute_sha3), &HashWidget);
g_signal_connect (HashWidget.hashCheck[4], "clicked", G_CALLBACK (compute_sha2), &HashWidget);
g_signal_connect (HashWidget.hashCheck[5], "clicked", G_CALLBACK (compute_sha3), &HashWidget);
g_signal_connect_swapped (HashWidget.hashCheck[6], "clicked", G_CALLBACK (compute_whirlpool), &HashWidget);
g_signal_connect_swapped (HashWidget.hashCheck[7], "clicked", G_CALLBACK (compute_gost94), &HashWidget);
result = gtk_dialog_run (GTK_DIALOG (dialog));
switch (result)
{
case GTK_RESPONSE_REJECT:
g_free (HashWidget.filename);
gtk_widget_destroy (dialog);
break;
}
}
The compute_* functions have the same codebase (except for sha2 and sha3 which have a 256/512 switch case):
static goffset get_file_size (const gchar *);
void
compute_sha3 ( GtkWidget *checkBt,
struct hashWidget_t *HashWidget)
{
gint bit;
if (g_strcmp0 (gtk_widget_get_name (checkBt), "BtSha3_256") == 0)
bit = 256;
else if (g_strcmp0 (gtk_widget_get_name (checkBt), "BtSha3_512") == 0)
bit = 512;
if (bit == 256)
{
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (HashWidget->hashCheck[3])))
{
gtk_entry_set_text (GTK_ENTRY (HashWidget->hashEntry[3]), "");
goto fine;
}
else if (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (HashWidget->hashEntry[3])), -1) == 64)
goto fine;
}
else
{
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (HashWidget->hashCheck[5])))
{
gtk_entry_set_text (GTK_ENTRY (HashWidget->hashEntry[5]), "");
goto fine;
}
else if (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (HashWidget->hashEntry[5])), -1) == 128)
goto fine;
}
guchar *digest;
gchar *hash;
GError *err = NULL;
gint fd, i, retVal;
goffset fileSize, doneSize = 0, diff = 0, offset = 0;
guint8 *fAddr;
struct sha3_256_ctx ctx256;
struct sha3_512_ctx ctx512;
if (bit == 256)
{
digest = g_malloc (SHA3_256_DIGEST_SIZE);
hash = g_malloc (65);
}
else
{
digest = g_malloc (SHA3_512_DIGEST_SIZE);
hash = g_malloc (129);
}
if (digest == NULL)
{
g_printerr ("sha2: error during memory allocation\n");
return;
}
if (hash == NULL)
{
g_printerr ("sha2: error during memory allocation\n");
g_free (digest);
return;
}
fd = g_open (HashWidget->filename, O_RDONLY | O_NOFOLLOW);
if (fd == -1)
{
g_printerr ("sha2: %s\n", g_strerror (errno));
return;
}
fileSize = get_file_size (HashWidget->filename);
if (bit == 256)
sha3_256_init (&ctx256);
else
sha3_512_init (&ctx512);
if (fileSize < BUF_FILE)
{
fAddr = mmap (NULL, fileSize, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
if (fAddr == MAP_FAILED)
{
g_printerr ("sha2: %s\n", g_strerror (errno));
g_free (digest);
g_free (hash);
g_close (fd, &err);
return;
}
if (bit == 256)
sha3_256_update (&ctx256, fileSize, fAddr);
else
sha3_512_update (&ctx512, fileSize, fAddr);
retVal = munmap (fAddr, fileSize);
if (retVal == -1)
{
g_printerr ("sha2: %s\n", g_strerror (errno));
g_free (digest);
g_free (hash);
g_close (fd, &err);
return;
}
goto nowhile;
}
while (fileSize > doneSize)
{
fAddr = mmap (NULL, BUF_FILE, PROT_READ, MAP_FILE | MAP_SHARED, fd, offset);
if (fAddr == MAP_FAILED)
{
g_printerr ("sha2: %s\n", g_strerror (errno));
g_free (digest);
g_free (hash);
g_close (fd, &err);
return;
}
if (bit == 256)
sha3_256_update(&ctx256, BUF_FILE, fAddr);
else
sha3_512_update(&ctx512, BUF_FILE, fAddr);
doneSize += BUF_FILE;
diff = fileSize - doneSize;
offset += BUF_FILE;
if (diff < BUF_FILE && diff > 0)
{
fAddr = mmap (NULL, diff, PROT_READ, MAP_FILE | MAP_SHARED, fd, offset);
if (fAddr == MAP_FAILED)
{
g_printerr ("sha2: %s\n", g_strerror (errno));
g_free (digest);
g_free (hash);
g_close (fd, &err);
return;
}
if (bit == 256)
sha3_256_update(&ctx256, diff, fAddr);
else
sha3_512_update(&ctx512, diff, fAddr);
retVal = munmap(fAddr, BUF_FILE);
if(retVal == -1){
g_printerr ("sha2: %s\n", g_strerror (errno));
g_free (digest);
g_free (hash);
g_close (fd, &err);
return;
}
break;
}
retVal = munmap(fAddr, BUF_FILE);
if(retVal == -1)
{
g_printerr ("sha2: %s\n", g_strerror (errno));
g_free (digest);
g_free (hash);
g_close (fd, &err);
return;
}
}
nowhile:
if (bit == 256)
{
sha3_256_digest(&ctx256, SHA3_256_DIGEST_SIZE, digest);
for(i=0; i<32; i++)
g_sprintf (hash+(i*2), "%02x", digest[i]);
hash[64] = '\0';
gtk_entry_set_text (GTK_ENTRY (HashWidget->hashEntry[3]), hash);
}
else
{
sha3_512_digest(&ctx512, SHA3_512_DIGEST_SIZE, digest);
for(i=0; i<64; i++)
g_sprintf (hash+(i*2), "%02x", digest[i]);
hash[128] = '\0';
gtk_entry_set_text (GTK_ENTRY (HashWidget->hashEntry[5]), hash);
}
g_close (fd, &err);
g_free (digest);
g_free (hash);
fine:
return;
}
static goffset
get_file_size (const gchar *filePath)
{
GFileInfo *info;
GFile *file;
GError *error = NULL;
const gchar *attributes = "standard::*";
GFileQueryInfoFlags flags = G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS;
GCancellable *cancellable = NULL;
goffset fileSize;
file = g_file_new_for_path (filePath);
info = g_file_query_info (file, attributes, flags, cancellable, &error);
fileSize = g_file_info_get_size (info);
g_object_unref(file);
return fileSize;
}
The problem is that i'm getting a segfault when i'm trying to compute hashes (below there is the output of 3 segfault):
polcrypt[1678]: segfault at 7f48a40018d8 ip 00007f48e0ae9e8d sp 00007fff2ce02230 error 4 in libgtk-3.so.0.1200.2[7f48e08ac000+51a000]
gmain[1883]: segfault at 7f8814001b38 ip 00007f885f2a7f8b sp 00007f884ab1fc70 error 6 in libglib-2.0.so.0.4000.0[7f885f262000+130000]
polcrypt[1941]: segfault at 7f885c001b18 ip 00007f88868d045f sp 00007fffa35ddc60 error 7 in libglib-2.0.so.0.4000.0[7f888686c000+130000
Sometimes i got the segfault after 1 computation, sometimes after 3 and so on but what i have noticed is that the segfault occurs only when a file bigger than 10M is selected.
I think the problem is inside the main.c file because if i put a g_print at the end of the compute_* functions, the print statement is printed on the screen before getting the segfault.
I'm developing on Gentoo ~x64 and Fedora 20 both with GNOME 3.12, Glib 2.40, GCC 4.8 and libc-2.19
EDIT (core dump):
Reading symbols from polcrypt...(no debugging symbols found)...done.
[New LWP 8848]
[New LWP 8849]
[New LWP 8850]
[New LWP 8853]
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./polcrypt'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f38888fada7 in g_slice_alloc () from /usr/lib64/libglib-2.0.so.0
and then the full bt:
(gdb) bt full
#0 0x00007f38888fada7 in g_slice_alloc () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
#1 0x00007f38888b4d35 in g_array_sized_new () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
#2 0x00007f388a4d181f in gtk_widget_path_new () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#3 0x00007f388a4cdc76 in _gtk_widget_create_path () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#4 0x00007f388a2f2820 in gtk_container_real_get_path_for_child () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#5 0x00007f388a2f7cb7 in gtk_container_get_path_for_child () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#6 0x00007f388a2b265d in gtk_box_get_path_for_child () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#7 0x00007f388a2f7cb7 in gtk_container_get_path_for_child () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#8 0x00007f388a2f2820 in gtk_container_real_get_path_for_child () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#9 0x00007f388a2f7cb7 in gtk_container_get_path_for_child () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#10 0x00007f388a4cdc0d in gtk_widget_get_path () from /usr/lib64/libgtk-3.so.0
---Type <return> to continue, or q <return> to quit---
No symbol table info available.
#11 0x00007f388016d100 in adwaita_engine_render_focus () from /usr/lib64/gtk-3.0/3.0.0/theming-engines/libadwaita.so
No symbol table info available.
#12 0x00007f388a4293e1 in gtk_render_focus () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#13 0x00007f388a2e076c in gtk_check_button_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#14 0x00007f388a392ebe in _gtk_marshal_BOOLEAN__BOXEDv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#15 0x00007f388a4bd4dd in gtk_widget_draw_marshallerv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#16 0x00007f3888bda53f in _g_closure_invoke_va () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#17 0x00007f3888bf2f98 in g_signal_emit_valist () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#18 0x00007f3888bf3bfa in g_signal_emit () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#19 0x00007f388a4cad16 in _gtk_widget_draw_internal.part.62 () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#20 0x00007f388a4cc6eb in _gtk_widget_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
---Type <return> to continue, or q <return> to quit---
#21 0x00007f388a2f7abd in gtk_container_propagate_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#22 0x00007f388a2f7b82 in gtk_container_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#23 0x00007f388a3570a2 in gtk_grid_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#24 0x00007f388a392ebe in _gtk_marshal_BOOLEAN__BOXEDv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#25 0x00007f388a4bd4dd in gtk_widget_draw_marshallerv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#26 0x00007f3888bda53f in _g_closure_invoke_va () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#27 0x00007f3888bf2f98 in g_signal_emit_valist () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#28 0x00007f3888bf3bfa in g_signal_emit () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#29 0x00007f388a4cad16 in _gtk_widget_draw_internal.part.62 () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#30 0x00007f388a4cc6eb in _gtk_widget_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#31 0x00007f388a2f7abd in gtk_container_propagate_draw () from /usr/lib64/libgtk-3.so.0
---Type <return> to continue, or q <return> to quit---
No symbol table info available.
#32 0x00007f388a2f7b82 in gtk_container_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#33 0x00007f388a2b4882 in gtk_box_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#34 0x00007f388a392ebe in _gtk_marshal_BOOLEAN__BOXEDv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#35 0x00007f388a4bd4dd in gtk_widget_draw_marshallerv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#36 0x00007f3888bda53f in _g_closure_invoke_va () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#37 0x00007f3888bf2f98 in g_signal_emit_valist () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#38 0x00007f3888bf3bfa in g_signal_emit () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#39 0x00007f388a4cad16 in _gtk_widget_draw_internal.part.62 () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#40 0x00007f388a4cc6eb in _gtk_widget_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#41 0x00007f388a2f7abd in gtk_container_propagate_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
---Type <return> to continue, or q <return> to quit---
#42 0x00007f388a2f7b82 in gtk_container_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#43 0x00007f388a4dd4a4 in gtk_window_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#44 0x00007f388a392ebe in _gtk_marshal_BOOLEAN__BOXEDv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#45 0x00007f388a4bd4dd in gtk_widget_draw_marshallerv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#46 0x00007f3888bda5c7 in _g_closure_invoke_va () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#47 0x00007f3888bf2f98 in g_signal_emit_valist () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#48 0x00007f3888bf3bfa in g_signal_emit () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#49 0x00007f388a4cad16 in _gtk_widget_draw_internal.part.62 () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#50 0x00007f388a4cc35f in _gtk_widget_draw_windows () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#51 0x00007f388a4cc5af in _gtk_widget_draw () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#52 0x00007f388a4cc903 in gtk_widget_send_expose () from /usr/lib64/libgtk-3.so.0
---Type <return> to continue, or q <return> to quit---
No symbol table info available.
#53 0x00007f388a392435 in gtk_main_do_event () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#54 0x00007f3889f8414b in _gdk_window_process_updates_recurse_helper () from /usr/lib64/libgdk-3.so.0
No symbol table info available.
#55 0x00007f3889f82545 in gdk_window_process_updates_internal () from /usr/lib64/libgdk-3.so.0
No symbol table info available.
#56 0x00007f3889f8266f in gdk_window_process_updates_with_mode () from /usr/lib64/libgdk-3.so.0
No symbol table info available.
#57 0x00007f3888bda5c7 in _g_closure_invoke_va () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#58 0x00007f3888bf2f98 in g_signal_emit_valist () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#59 0x00007f3888bf4132 in g_signal_emit_by_name () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#60 0x00007f3889f7c8b0 in gdk_frame_clock_paint_idle () from /usr/lib64/libgdk-3.so.0
No symbol table info available.
#61 0x00007f3889f6ee68 in gdk_threads_dispatch () from /usr/lib64/libgdk-3.so.0
No symbol table info available.
#62 0x00007f38888e0283 in g_timeout_dispatch () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
---Type <return> to continue, or q <return> to quit---
#63 0x00007f38888df865 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
#64 0x00007f38888dfbc8 in g_main_context_iterate.isra () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
#65 0x00007f38888dfe8a in g_main_loop_run () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
#66 0x00007f388a31a230 in gtk_dialog_run () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#67 0x000000000040a0be in compute_hash ()
No symbol table info available.
#68 0x000000000040871d in choose_file ()
No symbol table info available.
#69 0x00007f3888bda5c7 in _g_closure_invoke_va () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#70 0x00007f3888bf2f98 in g_signal_emit_valist () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#71 0x00007f3888bf3bfa in g_signal_emit () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#72 0x00007f388a2bfacd in gtk_button_do_release () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#73 0x00007f388a2bfb13 in gtk_real_button_released () from /usr/lib64/libgtk-3.so.0
---Type <return> to continue, or q <return> to quit---
No symbol table info available.
#74 0x00007f3888bda398 in g_closure_invoke () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#75 0x00007f3888beb467 in signal_emit_unlocked_R () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#76 0x00007f3888bf3939 in g_signal_emit_valist () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#77 0x00007f3888bf3bfa in g_signal_emit () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#78 0x00007f388a2bea31 in gtk_button_button_release () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#79 0x00007f388a392ebe in _gtk_marshal_BOOLEAN__BOXEDv () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#80 0x00007f3888bda5c7 in _g_closure_invoke_va () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#81 0x00007f3888bf2f98 in g_signal_emit_valist () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#82 0x00007f3888bf3bfa in g_signal_emit () from /usr/lib64/libgobject-2.0.so.0
No symbol table info available.
#83 0x00007f388a4c0b54 in gtk_widget_event_internal () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
---Type <return> to continue, or q <return> to quit---
#84 0x00007f388a39093c in propagate_event () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#85 0x00007f388a3923b5 in gtk_main_do_event () from /usr/lib64/libgtk-3.so.0
No symbol table info available.
#86 0x00007f3889f9cc72 in gdk_event_source_dispatch () from /usr/lib64/libgdk-3.so.0
No symbol table info available.
#87 0x00007f38888df984 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
#88 0x00007f38888dfbc8 in g_main_context_iterate.isra () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
#89 0x00007f38888dfc6c in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
No symbol table info available.
#90 0x00007f3888ebe0ec in g_application_run () from /usr/lib64/libgio-2.0.so.0
No symbol table info available.
#91 0x00000000004082ff in main ()
No symbol table info available.
Problem found!
The munmap function in this snippet must take diff as length arg and not BUF_FILE.
if (diff < BUF_FILE && diff > 0)
{
fAddr = mmap (NULL, diff, PROT_READ, MAP_FILE | MAP_SHARED, fd, offset);
retVal = munmap(fAddr, BUF_FILE); //wrong
retVal = munmap(fAddr, diff); //correct
break;
}
I am using mime_content_type() in PHP 5.5 to get a MIME type, but it throws fatal: error function not found.
How can I achieve this on PHP 5.5?
Make use of the finfo() functions.
A simple illustration:
<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, "path/to/image_dir/image.gif");
finfo_close($finfo);
OUTPUT :
image/gif
Note : Windows users must include the bundled php_fileinfo.dll DLL file in php.ini to enable this extension.
I've spent too much time trying to get the finfo functions to work, properly. I finally just ended up creating my own function to match the file extension to any array of mime types. It's not a full-proof way of assuring that the files are truly what the extension denotes them to be, but that problem can be mitigated by how you process I/O of said files on your server(s).
function mime_type($file) {
// there's a bug that doesn't properly detect
// the mime type of css files
// https://bugs.php.net/bug.php?id=53035
// so the following is used, instead
// src: http://www.freeformatter.com/mime-types-list.html#mime-types-list
$mime_type = array(
"3dml" => "text/vnd.in3d.3dml",
"3g2" => "video/3gpp2",
"3gp" => "video/3gpp",
"7z" => "application/x-7z-compressed",
"aab" => "application/x-authorware-bin",
"aac" => "audio/x-aac",
"aam" => "application/x-authorware-map",
"aas" => "application/x-authorware-seg",
"abw" => "application/x-abiword",
"ac" => "application/pkix-attr-cert",
"acc" => "application/vnd.americandynamics.acc",
"ace" => "application/x-ace-compressed",
"acu" => "application/vnd.acucobol",
"adp" => "audio/adpcm",
"aep" => "application/vnd.audiograph",
"afp" => "application/vnd.ibm.modcap",
"ahead" => "application/vnd.ahead.space",
"ai" => "application/postscript",
"aif" => "audio/x-aiff",
"air" => "application/vnd.adobe.air-application-installer-package+zip",
"ait" => "application/vnd.dvb.ait",
"ami" => "application/vnd.amiga.ami",
"apk" => "application/vnd.android.package-archive",
"application" => "application/x-ms-application",
// etc...
// truncated due to Stack Overflow's character limit in posts
);
$extension = \strtolower(\pathinfo($file, \PATHINFO_EXTENSION));
if (isset($mime_type[$extension])) {
return $mime_type[$extension];
} else {
throw new \Exception("Unknown file type");
}
}
Edit:
I'd like to address Davuz's comment (since it keeps getting up-voted) and remind everyone that I put in the pseudo disclaimer at the top that this isn't "full-proof." So, please keep that in mind when considering the approach I've offered in my answer.
mime_content_type() is not deprecated and works fine.
Why is mime_content_type() deprecated in PHP?
http://php.net/manual/en/function.mime-content-type.php
As of PHP 5.3, it's even built-in.
$finfo = finfo_open(FILEINFO_MIME_TYPE); should do it.
Taken from the php.net docs. Your function is deprecated and probably already removed.
http://www.php.net/manual/en/function.finfo-file.php
You should understand that file_get_contents will upload whole file to the memory, it is not good way to get only mime type. You don't need to use buffer method and file_get_contents function in this case.
To prevent any errors and warnings, better do like this.
$filename = 'path to your file';
if (class_exists('finfo')) {
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (is_object($finfo)) {
echo $finfo->file($filename);
}
} else {
echo 'fileinfo did not installed';
}
Also you should know $finfo->file will throw PHP Warning if it fail.
If fileinfo is not installed properly, and you have a fresh version of PHP, you can get mime type from headers.
You can use cURL to get mime type from headers.
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_HEADER => true,
CURLOPT_NOBODY => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 1,
CURLOPT_URL => $link)
);
$headers = curl_exec($ch);
curl_close($ch);
if (preg_match('/Content-Type:\s(.*)/i', $headers, $matches)) {
echo trim($matches[1], "\t\n\r");
}else {
echo 'There is no content type in the headers!';
}
Also you can use get_headers function, but it more slow than cURL request.
$url = 'http://www.example.com';
$headers = get_headers($url, 1);
echo $headers['Content-Type'];
Get the image size using:
$infFil=getimagesize($the_file_name);
and
echo $infFil["mime"]
The getimagesize returns an associative array which have a MIME key and obviously the image size too
I used it and it works
I use the MimeTypeTool from Bat (https://github.com/lingtalfi/Bat)
It uses fileinfo if available, and defaults back to an "extension => mime type" mapping otherwise.
This is the best solution I found by combining two very good posts
// Thanks to http://php.net/manual/en/function.mime-content-type.php#87856
function getMimeContentType($filename, $ext)
{
if(!function_exists('mime_content_type'))
{
if($mime_types = getMimeTypes())
{
if (array_key_exists($ext, $mime_types))
{
return $mime_types[$ext];
}
elseif (function_exists('finfo_open'))
{
$finfo = finfo_open(FILEINFO_MIME);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);
return $mimetype;
}
}
return 'application/octet-stream';
}
return mime_content_type($filename);
}
// Thanks to http://php.net/manual/en/function.mime-content-type.php#107798
function getMimeTypes()
{
$url = 'http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types';
$mimes = array();
foreach(#explode("\n",#file_get_contents($url)) as $x)
{
if(isset($x[0]) && $x[0]!=='#' && preg_match_all('#([^\s]+)#', $x, $out) && isset($out[1]) && ($c = count($out[1])) > 1)
{
for($i=1; $i < $c; $i++)
{
$mimes[$out[1][$i]] = $out[1][0];
}
}
}
return (#sort($mimes)) ? $mimes : false;
}
Use it link this:
$filename = '/path/to/the/file.pdf';
$ext = strtolower(array_pop(explode('.',$filename)));
$content_type = getMimeContentType($filename, $ext);
Will continue to work even if the mime_content_type function is no longer supported in php.