C Query

neilofbodom

Member
Hi folks,

I have an assignment to do in C for a programming class. Basically, the idea is to convert an image to grayscale and apply a median filter to the grayscale image.

Here's my code:

#include "imageio.h"
#include "imageio.c"

int main(void)
{

int i, j, grey, temp, median;
int size = 3;
IMAGE image = loadImage("test.bmp");

int window[size];

RGB pixel = image.pixels[j];


for(i = 0; i < image.height; i++)
for(j = 0; j < image.width; j++)
{
// Get current pixel value

// RGB is defined in imageio.h

// Reduce intensity by 50%
pixel.R = pixel.R * 0.5;
pixel.G = pixel.G * 0.5;
pixel.B = pixel.B * 0.5;

// Convert to grayscale

grey = (0.299 * pixel.R + 0.587 * pixel.G + 0.144 * pixel.B);

pixel.R = grey;
pixel.G = grey;
pixel.B = grey;

// Place modified pixel back into its place
image.pixels[j] = pixel;
window = grey;
}

for (i = 0; i < (size*size)-1; i++)
for(j = 0; j < (size*size)-i-1; j++)
{
// sorting in ascending order, using bubble sort

if (window > window[i+1])
{
temp = window;
window = window[i+1];
window[i+1] = temp;
} else continue;

}

// finding the median

median = window[(((size*size)-1)/2)];

pixel.R = median;
pixel.G = median;
pixel.B = median;

image.pixels[j] = pixel;



saveImage("mod_test_image.bmp", image);

}

I have no idea what is wrong with my code. When I run the program, "main.exe has stopped working" comes up. I'm assuming it's an infinite loop, but honestly I can't see the problem.

The idea behind how I tackled the problem is this:

An odd-sized window (lecturer told us to ignore cases for even-size) is moved across the image and the pixels are arranged in ascending order. The median of the window is then found and replaced back into the original image.

Could you help me please?

If you need the header files let me know.

Cheers!
 
Have you ever used GDB before? I'm at work, so I can't really run it at the moment, but with GDB you'll be able to see exactly what's going on.
 
Have you ever used GDB before? I'm at work, so I can't really run it at the moment, but with GDB you'll be able to see exactly what's going on.

I have never used GDB before. I'll try giving it a shot. Any specific version I should download or any will do?
 
Can you wrap the code in code tags? I can barely read that.

Anyway, infinite loops by themselves don't cause the application to crash/"stop unexpectedly working", it would just hang until manually terminated. If a C program crashes, you're almost certainly touching memory you're not supposed to.

EDIT: What compiler are you using? GDB should come with mingw/cygwin gcc, but I'm pretty sure you can't debug executables generated by other compilers in general.
 
Last edited:
Can you wrap the code in code tags? I can barely read that.

Anyway, infinite loops by themselves don't cause the application to crash/"stop unexpectedly working", it would just hang until manually terminated. If a C program crashes, you're almost certainly touching memory you're not supposed to.

EDIT: What compiler are you using? GDB should come with mingw/cygwin gcc, but I'm pretty sure you can't debug executables generated by other compilers in general.

I'm using CodeBlocks with mingw and gnu gcc
 
Here's a wiki on using code::block's debugger (which used gdb);

If you could give us the error that's crashing the application we could help more. If hackapelite is right, then you maybe you are accessing indices in your array that are out of bounds.
 
Ok so I'm now getting an error in my imageio.c file. "undefined reference to WinMain@16"

imageio.c is as follows:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "imageio.h"


// Global declerations;
bmpType type;
fileHeader file_header;
infoHeader info_header;

// Load a bitmap file into memory
IMAGE loadImage(const char *filename)
{
    // Open file for reading
    FILE *fp = fopen(filename, "rb");
    if (fp == NULL)
    {
        fprintf(stderr, "Could not read %s. Exiting\n", filename);
        exit(-1);
    }

    // Read first few headers
    fread((char *) &type, sizeof(type), 1, fp);
    fread((char *) &file_header, sizeof(fileHeader), 1, fp);
    fread((char *) &info_header, sizeof(infoHeader), 1, fp);

    // Sanity checking
    if (info_header.compressType)
    {
        fprintf(stderr, "Compressed image not supported. Exiting\n");
        exit(-1);
    }

    // Allocate array for image data
    unsigned size = info_header.width * info_header.height;
    RGB *image = (RGB *) malloc(size * sizeof(RGB));
    memset(image, 0, size * sizeof(RGB));

    // Seek start of image data
    fseek(fp, file_header.offset, SEEK_SET);

    // Read image data into array
    unsigned read = fread((char *) image, 1, sizeof(RGB) * size, fp);
    if (read != size * sizeof(RGB))
    {
        fprintf(stderr, "Unable to read image file. Exiting\n");
        exit(-1);
    }

    // Format data for output
    IMAGE output;
    output.height = info_header.height;
    output.width = info_header.width;

    unsigned i;
    RGB **imagedata = (RGB **) malloc(output.height * sizeof(RGB*));
    for(i = 0; i < output.height; i++)
    {
        imagedata[i] = (RGB*) malloc(output.width * sizeof(RGB));
        memcpy(imagedata[i], &image[i * output.width], output.width * sizeof(RGB));
    }
    output.pixels = imagedata;
    free(image);

    return output;
}

// Save a bitmap to disk
void saveImage(char* filename, IMAGE image)
{
    // Open file for writing
    FILE *fp = fopen(filename, "wb");
    if (fp == NULL)
    {
        fprintf(stderr, "Unable to open file for writing. Exiting\n");
        exit(-1);
    }

    // Check if we have file information
    if (info_header.headerSz == 0)
    {
        fprintf(stderr, "Image information not loaded. Exiting\n");
        exit(-1);
    }

    // Write header information to file
    fwrite((char *) &type, sizeof(bmpType), 1, fp);
    info_header.width = image.width;
    info_header.height = image.height;
    fwrite((char *) &file_header, sizeof(fileHeader), 1, fp);
    fwrite((char *) &info_header, sizeof(infoHeader), 1, fp);
    fflush(fp);

    // Write image data to disk
    unsigned i;

    for(i = 0; i < image.height; i++)
        fwrite((char *) image.pixels[i], sizeof(RGB), image.width, fp);
    fflush(fp);
}

The other header file (imageio.h) is as follows:

Code:
#ifndef IMAGEIO
#define IMAGEIO

// Header and data format structures

typedef struct BMPTYPE{
    unsigned char magic[2];
} bmpType;

typedef struct FILEHEADER {
    unsigned int size;
    unsigned short res1;
    unsigned short res2;
    unsigned int offset;
} fileHeader;

typedef struct INFOHEADER
{
    unsigned int headerSz;
    unsigned int width;
    unsigned int height;
    unsigned short nplanes;
    unsigned short bitspp;
    unsigned int compressType;
    unsigned int bytesz;
    unsigned int hres;
    unsigned int vres;
    unsigned int ncolors;
    unsigned int nimpcolors;
} infoHeader;

typedef struct rgb
{
    unsigned char B, G, R;
} RGB;

typedef struct IMAGESTRUCT
{
    unsigned int height;
    unsigned int width;
    RGB **pixels;
} IMAGE;

// Function definitions
void saveImage(char* filename, IMAGE image);
IMAGE loadImage(const char *filename);

#endif
 
If CodeBlocks is giving you trouble,try using Dev-C++ IDE instead.
With it you can create C and C++ programs and it also uses the same compiler.
If your code in Dev-C++ gives you some errors,copy the error output in your reply.And if possible also give us the number of each line on which the error occured.
 
Last edited:
Back
Top