Issue loading BMP image using SDL_image - c

I am new to SDL_image and I am trying to use it in a C file to load a BMP image.
To that end, I have written the following code:
#include "SDL/SDL.h"
#include "SDL_image.h"
SDL_RWops *rwop;
rwop = SDL_RWFromFile("sample.bmp", "rb");
However, for some reason, although rwop after those lines are executed is not NULL anymore, IMG_isBMP(rwop) is 0.
Any idea what could be wrong?

Perhaps better example. This (might) yield more information and perhaps if BMP is supported:
https://www.libsdl.org/projects/SDL_image/docs/SDL_image_32.html
You could also try using IMG_LoadBMP_RW as per example here:
https://www.libsdl.org/projects/SDL_image/docs/SDL_image_16.html#SEC16
#include <stdio.h>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
int main(int argc, char *argv[])
{
const char *fn = "sample.bmp";
SDL_Surface *surf;
if (argc > 1)
fn = argv[1];
if ((surf = SDL_LoadBMP(fn)) == NULL) {
printf("SDL_loadBMP failed: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
printf("%s is bmp\n", fn);
SDL_FreeSurface(surf);
SDL_Quit();
return 0;
}
Old answer:
Tested and validated:
#include <stdio.h>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
int main(int argc, char *argv[])
{
const char *fn = "sample.bmp";
int v;
SDL_RWops *rwop;
if (argc > 1)
fn = argv[1];
if ((rwop = SDL_RWFromFile(fn, "rb")) == NULL) {
printf("SDL_RWFromFile failed: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
v = IMG_isBMP(rwop);
printf("%s is bmp = %d\n", fn, v);
SDL_FreeRW(rwop);
SDL_Quit();
return 0;
}
Compiled with:
gcc -Wall -Wextra -pedantic -o sdl sdl.c `sdl-config --libs` -lSDL_image
Yield for BMP images, e.g.:
$ ./sdltest lena.bmp
lena.bmp is bmp = 1

Related

Can't figure out seg fault

Why do I keep getting a set fault when I try and pass -H in the command line as a flag? -h (help) is working perfectly but -H(header) messes up every single time.
I have a main function as well which calls parse_command_line by passing the argc & argc.
the bool is defined as bool header = false;
the file is char** file = NULL;
and the reason I have the file+=1; in the code is so that it compiles because I am using a makefile that changes all warnings into errors.
#include "parse.h" /* prototypes for exported functions */
#include "../main/unused.h"
#include <stdlib.h>
#include <getopt.h>
#include <stdio.h>
#include <stdint.h>
int
parse_command_line (int argc, char **argv, bool *header, char **file)
{
int oc = 0;
file += 1;
bool help = false;
struct option long_options[] =
{
{"header", no_argument, NULL, 'H'},
{"help", no_argument, NULL, 'h'},
{0, 0, 0, 0}
};
while ((oc = getopt_long(argc, argv, "+Hh", long_options, NULL)) != -1)
{
printf("The value of oc = %d\n", oc);
switch(oc)
{
case 'h':
help = true;
break;
case 'H':
printf("inside case H");
*header = true;
break;
case '?':
fprintf(stderr, "Unknown flag = -%c, type -h or --help for help!\n", optopt);
exit(EXIT_FAILURE);
break;
default:
break;
}
}
printf("Out of loop"); if (optind+1 != argc)
{
fprintf(stderr, "Uh oh, invalid input! Try again with -h or --help for help!\n");
exit(EXIT_FAILURE);
}
if (help)
{
printf("\nHaving some trouble? Let me show you the ropes!\n\n");
printf("Format: ydi <option(s)> mini-elf-file\n\n");
printf("Here's your options:\n");
printf("-h --help Display usage\n");
printf("-H --header Show the Mini-Elf header\n");
exit(1);
}
if (header)
{
printf("Inside HEader");
FILE *file;
uint16_t nums[6];
file = fopen(argv[optind], "r");
#define STRUCT_ITEMS 7
fread(nums, 16, 6, file);
int cur_print;
for (cur_print = 0; cur_print < STRUCT_ITEMS; cur_print++)
{
printf("%d ", nums[cur_print]);
}
}
return 0;
}
My parse.h file is as follows:
#ifndef __PARSE_COMMAND_LINE__
#define __PARSE_COMMAND_LINE__
#include <stdbool.h>
int parse_command_line (int argc, char **argv, bool *header, char **file);
#endif
There are other files such as elf.h and elf.c which I have not implemented and are not called at all at this point, which leads me to believe they are not going to be the problem and don't need to post the small 2 line files. My main function is as follows:
#include <stdio.h> /* standard I/O */
#include <stdlib.h>
#include "unused.h" /* UNUSED macro */
#include "../cmdline/parse.h" /* command line parser */
#include "../y86/elf.h" /* Mini-ELF format */
int
main (int argc UNUSED, char **argv UNUSED)
{
printf ("Congratulations, you have compiled your source code!\n");
bool header = false;
char **file = NULL;
parse_command_line (argc, argv, &header, file);
return 0;
}
And the file unused.h (because the compiler will make unused variables an error instead of warning) is as follows:
#ifndef __UNUSED__
#define __UNUSED__
#define UNUSED __attribute__ ((unused))
#endif
The code doesn't check the return value of fopen, which will be NULL in case of an error. Dereferencing NULL in the fread call causes a segfault.

Why PAM module code isn't working in my ubuntu?

I implemented basic PAM module and test application from this github link.
In the src folder it has a simple PAM module and test code for it.
PAM module code mypam.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
/* expected hook */
PAM_EXTERN int pam_sm_setcred( pam_handle_t *pamh, int flags, int argc, const char **argv ) {
return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) {
printf("Acct mgmt\n");
return PAM_SUCCESS;
}
/* expected hook, this is where custom stuff happens */
PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char **argv ) {
int retval;
const char* pUsername;
retval = pam_get_user(pamh, &pUsername, "Username: ");
printf("Welcome %s\n", pUsername);
if (retval != PAM_SUCCESS) {
return retval;
}
if (strcmp(pUsername, "backdoor") != 0) {
return PAM_AUTH_ERR;
}
return PAM_SUCCESS;
}
Test code test.c:
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>
const struct pam_conv conv = {
misc_conv,
NULL
};
int main(int argc, char *argv[]) {
pam_handle_t* pamh = NULL;
int retval;
const char* user = "nobody";
if(argc != 2) {
printf("Usage: app [username]\n");
exit(1);
}
user = argv[1];
retval = pam_start("check_user", user, &conv, &pamh);
// Are the credentials correct?
if (retval == PAM_SUCCESS) {
printf("Credentials accepted.\n");
retval = pam_authenticate(pamh, 0);
}
// Can the accound be used at this time?
if (retval == PAM_SUCCESS) {
printf("Account is valid.\n");
retval = pam_acct_mgmt(pamh, 0);
}
// Did everything work?
if (retval == PAM_SUCCESS) {
printf("Authenticated\n");
} else {
printf("Not Authenticated\n");
}
// close PAM (end session)
if (pam_end(pamh, retval) != PAM_SUCCESS) {
pamh = NULL;
printf("check_user: failed to release authenticator\n");
exit(1);
}
return retval == PAM_SUCCESS ? 0 : 1;
}
I built the module according to the github link instructions:
gcc -fPIC -fno-stack-protector -c src/mypam.c
sudo ld -x --shared -o /lib/security/mypam.so mypam.o
sudo ld -x --shared -o /lib/x86_64-linux-gnu/security/mypam.so mypam.o
gcc -o pam_test src/test.c -lpam -lpam_misc
I put below two command into /etc/pam.d/common-auth at the top.
auth sufficient mypam.so
account sufficient mypam.s
According to the site:
To run the test program, just do: pam_test backdoor and you should get
some messages saying that you're authenticated!
But I got following error:
abnormal#abnormal:~/Desktop$ pam_test backdoor
No command 'pam_test' found, did you mean:
Command 'pim_test' from package 'styx' (universe)
pam_test: command not found
abnormal#abnormal:~/Desktop$
what sholud I do now? I am using ubuntu 14,04 LTS. Please help.
There's nothing wrong with the code, but the invocation. You shoud use this:
abnormal#abnormal:~/Desktop$ ./pam_test backdoor
Unlike Windows, the current directory usually is not part of the search PATH on Linux.

Not sure why I am getting an undefine refence to gss_str_to_oid error

I am using gssapi in C for the first time. I am trying to reconstruct example on Oracle doc http://docs.oracle.com/cd/E19683-01/816-1331/sampleprogs-1/index.html.
In my .c file I call gss_str_to_oid(&min_stat, &tok, oid); and get an undefined reference error. I included #include "gssapi.h" at the top of my .c file. In gssapi.h there is a function call
OM_uint32 KRB5_CALLCONV
gss_str_to_oid(
OM_uint32 *, /* minor_status */
gss_buffer_t, /* oid_str */
gss_OID *);
So what am I doing wrong? I thought that if you included #include "gssapi.h" it would give me access to function in gssapi. Both files are in my src folder. So what am I doing wrong. I am using eclipse and from what in my makefile under targets it says all: GSS-API.
I am including most of my code below.
main
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <error.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "gssapi.h"
#include "gssapi_ext.h"
#include "gss-misc.h"
/* global mech oid needed by display status, and acquire cred */
FILE *display_file;
gss_OID g_mechOid = GSS_C_NULL_OID;
void usage()
{
fprintf(stderr, "Usage: gss-client [-port port] [-d]"
" [-mech mechOid] host service msg\n");
exit(1);
}
static void parse_oid(char *mechanism, gss_OID *oid)
{
char *mechstr = 0, *cp;
gss_buffer_desc tok;
OM_uint32 maj_stat, min_stat;
if (isdigit(mechanism[0])) {
mechstr = malloc(strlen(mechanism)+5);
if (!mechstr) {
printf("Couldn't allocate mechanism scratch!\n");
return;
}
sprintf(mechstr, "{ %s }", mechanism);
for (cp = mechstr; *cp; cp++)
if (*cp == '.')
*cp = ' ';
tok.value = mechstr;
} else
tok.value = mechanism;
tok.length = strlen(tok.value);
maj_stat = gss_str_to_oid(&min_stat, &tok, oid);
if (maj_stat != GSS_S_COMPLETE) {
// display_status("str_to_oid", maj_stat, min_stat);
return;
}
if (mechstr)
free(mechstr);
}
int main(argc, argv)
int argc;
char **argv;
{
/* char *service_name, *hostname, *msg; */
char *msg;
char service_name[128];
char hostname[128];
char *mechanism = 0;
u_short port = 4444;
int use_file = 0;
OM_uint32 deleg_flag = 0, min_stat;
display_file = stdout;
/* Parse arguments. */
argc--; argv++;
while (argc) {
if (strcmp(*argv, "-port") == 0) {
argc--; argv++;
if (!argc) usage();
port = atoi(*argv);
} else if (strcmp(*argv, "-mech") == 0) {
argc--; argv++;
if (!argc) usage();
mechanism = *argv;
} else if (strcmp(*argv, "-d") == 0) {
deleg_flag = GSS_C_DELEG_FLAG;
} else if (strcmp(*argv, "-f") == 0) {
use_file = 1;
} else
break;
argc--; argv++;
}
if (argc != 3)
usage();
if (argc > 1) {
strcpy(hostname, argv[0]);
} else if (gethostname(hostname, sizeof(hostname)) == -1) {
perror("gethostname");
exit(1);
}
if (argc > 2) {
strcpy(service_name, argv[1]);
strcat(service_name, "#");
strcat(service_name, hostname);
}
msg = argv[2];
if (mechanism)
parse_oid(mechanism, &g_mechOid);
/* if (call_server(hostname, port, g_mechOid, service_name,
deleg_flag, msg, use_file) < 0)
exit(1);*/
/*
if (g_mechOid != GSS_C_NULL_OID)
(void) gss_release_oid(&min_stat, &gmechOid);
*/
return 0;
}
gssapi.h
/* New for V2 */
OM_uint32 KRB5_CALLCONV
gss_str_to_oid(
OM_uint32 *, /* minor_status */
gss_buffer_t, /* oid_str */
gss_OID *);
You just can't include the header you have to link the library either dynamically or statically. Is there some dll, lib, so, etc you need to add to your project? Without makefile or your project setup been shown in your question; I think you will not receive a very clear answer. Just including header file isn't enough, the undefined is not a compilation error but a linker error, which means its missing a reference because you are not linking the library to your program.
The documentation for GSSAPI in C and C++ in not the greatest. Turns out you need to download gssapi. Here is the link http://www.gnu.org/software/gss/manual/gss.html.
It is under download and install
So, I faced same problem.
I found out that you need to add some .so files to your project.
Just in case check that your system has libkrb5-dev packet (most likely it is already installed if you have gssapi.h).
Required files are stored in folder "/usr/lib/x86_64-linux-gnu/" (debian in my case):
I added libkdb5.so and libgssapi_krb5.so to QT .pro file and all works fine:
LIBS += -lkdb5
LIBS += -lgssapi_krb5
If you need to find that files .so use folloing commands:
apt-file update
dpkg -L libkrb5-dev

undefined reference to `_fcloseall'

I am having trouble compiling my program.
The error message is: undefined reference to `_fcloseall', I think it could be a missing library file at the beginning. It might be also useful to know that I am programming on Windows 8.1 + Cygwin. Which library could be missing or do you see any other mistake?
Here is the code:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
void cleanup1();
void cleanup2();
int main(int argc, char *argv[])
{
FILE * file;
if(argc < 2){
printf("\ncommand bsp10085 <file>");
exit(1);
}
assert(atexit(cleanup1) == 0);
assert(atexit(cleanup2) == 0);
if((datei = fopen(argv[1], "r")) != NULL){
printf("\nfile %s is being processed ..",argv[1]);
fclose(datei);
}
else
printf("\nfile '%s' is missing. ", argv[1]);
}
void cleanup1(){
printf("\nCleanup the rest");
}
void cleanup2(){
printf("\nClose all open files");
fflush(NULL);
_fcloseall();
}
I tried to compile your code (in ubuntu though) and i also got a warning: warning: implicit declaration of function ‘fcloseall’ [-Wimplicit-function-declaration] fcloseall();
I think that if you add
#define _GNU_SOURCE
before
#include<stdio.h>
your program should work fine. This is your code after i changed some other warnings as well:
#define _GNU_SOURCE
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
void cleanup1();
void cleanup2();
int main(int argc, char *argv[])
{
FILE *datei;
if(argc < 2){
printf("\ncommand bsp10085 <file>");
exit(1);
}
assert(atexit(cleanup1) == 0);
assert(atexit(cleanup2) == 0);
if((datei = fopen(argv[1], "r")) != NULL){
printf("\nfile %s is being processed ..",argv[1]);
fclose(datei);
}
else
printf("\nfile '%s' is missing. ", argv[1]);
return 0;
}
void cleanup1(){
printf("\nCleanup the rest");
}
void cleanup2(){
printf("\nClose all open files");
fflush(NULL);
fcloseall();
}

Error validating the contents of a file using regex in C

I am having a problem with the below code validating a file using regex. My file must only contain letters or numbers. My regular expression is:
#define to_find "^[a-zA-Z0-9]+$"
which is located in my main.h file. The below code is in my main.c
#include <ctype.h>
#include <errno.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "main.h"
int main(int argc, char * argv[])
{
int ret_val;
regex_t regex;
FILE *fp;
char line[1024];
if (regcomp(&regex, to_find, REG_EXTENDED) != 0)
{
fprintf(stderr, "Failed to compile regex '%s'\n", to_find);
return EXIT_FAILURE;
}
if (argc > 2)
{
printf("Usage: tree OR tree [filename]\n");
return EXIT_FAILURE;
}
else if (argc == 2)
{
fp = fopen(strcat(argv[1],".dat"), "r");
printf("file opened\n");
while ((fgets(line, 1024, fp)) != NULL)
{
line[strlen(line) - 1] = '\0';
if ((ret_val = regexec(&regex, line, 0, NULL, 0)) != 0);
{
printf("Error: %s\n", line);
return EXIT_FAILURE;
}
}
fclose(fp);
printf("File closed\n");
}
return 0;
}
My file I am reading is called names.dat and contains:
int
char
[
double
What is happening is it is kicking out at the very first line which it should kick out at the 3rd line. I am sure this is pretty simple to solve but it seems I have not figured it out. I would appreciate any help. Also, how do I deal with the
\n
character in the file? this file will have several lines. Thanks in advance.
You have some small errors but the one that cause the error is:
// Do you see this sweet little semicolon :P ----------------+
if ((ret_val = regexec(&regex, line, 0, NULL, 0)) != 0); // <+
{
printf("Error: %s\n", line);
return EXIT_FAILURE;
}
beside this line:
fp = fopen(strcat(argv[1],".dat"), "r");
You cannot add to argv, you need to create a new buffer to hold the data, create a buffer with PATH_MAX size add append the path to it. Here an improved version:
#include <ctype.h>
#include <errno.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <limits.h>
#define to_find "^[a-zA-Z0-9]+$"
int main(int argc, char * argv[])
{
int ret_val;
regex_t regex;
FILE *fp;
char file[PATH_MAX];
char line[1024];
if (regcomp(&regex, to_find, REG_EXTENDED) != 0)
{
fprintf(stderr, "Failed to compile regex '%s'\n", to_find);
return EXIT_FAILURE;
}
if (argc > 2)
{
printf("Usage: tree OR tree [filename]\n");
return EXIT_FAILURE;
}
else if (argc == 2)
{
sprintf(file, "%s.dat", argv[1]);
fp = fopen(file, "r");
if( fp == NULL ) {
perror("Error");
return -1;
}
printf("file opened\n");
while (fscanf(fp, "%1023s", line) > 0)
{
if ((ret_val = regexec(&regex, line, 0, NULL, 0)) != 0)
{
printf("Not match: %s\n", line);
//return EXIT_FAILURE;
} else {
printf("Match: %s\n", line);
}
}
regfree(&regex);
fclose(fp);
printf("File closed\n");
}
return 0;
}
See the diff: http://www.diffchecker.com/8itbz5dy
test:
$ gcc -Wall sample.c
$
$ cat name.dat
int
char
[
double
$ ./a.out name
file opened
Match: int
Match: char
Not match: [
Match: double
File closed
$

Resources