Reproducing an Image using C - c

I'm trying to write a program to blur an image, but first of am trying to see if I can even reproduce the image, pixel by pixel, in another file. I've allocated a 2-dimensional char array to hold the value of each pixel in the image.
Note: The image is in grayscale, and it is of type .raw
However, whenever I attempt to read the pixels into my 2D array, my program crashes. I feel like it has something to do with me not looping through the dimensions of the image correctly, but I'm not sure.
Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fin, *fout;
char path_in[64], path_out[64], **rev, px;
int width, height, read, i, j;
printf("Input file name: ");
scanf("%s", path_in);
printf("Output file name: ");
scanf("%s", path_out);
printf("Width of image (in pixels): ");
scanf("%d", &width);
printf("Height of image (in pixels): ");
scanf("%d", &height);
fin = fopen(path_in, "rb");
fout = fopen(path_out, "wb");
row = 0;
rev = (char **)malloc(height * sizeof(char));
for(i = 0; i < width; i++)
rev[i] = (char *)malloc(width * sizeof(char));
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
read = fread(&px, sizeof(char), 1, fin);
rev[i][j] = px;
}
}
fclose(fout);
fclose(fin);
return 0;
}
My program is pretty narrow, as it only accepts grayscale .raw image type.

Change these lines as this:
row = 0;
rev = malloc(height * sizeof *rev);
for(i = 0; i < width; i++)
rev[i] = malloc(width * sizeof **rev);
You were allocating memory for height chars, not for height pointers to chars, as you intended.
Also, don't cast the result of malloc if developing with C

This line: rev = (char **)malloc(height * sizeof(char));
should be rev = (char **)malloc(height * sizeof(char*));

I think is better to use contiguous memory to manage the image!
Using char ** in the way as in your code you don't have a block of memory that contains the whole image, but a lot of not contiguous vectors each one containing a line!
The following code reads the image in a contiguous block of memory using only one malloc:
char * rev;
/* HERE your code to insert width and height */
rev = malloc(height * width *sizeof(char));
if (rev==NULL) {
/* Ops! The buffer is not allocated!!! */
}
/* HERE you open the file and so on */
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
read = fread(&rev[i*width+j], sizeof(char), 1, fin);
if (read!=1) { /* 1 is the number of bytes fread reads if ok */
/* Ops, there's a problem! The fread didn't read! */
}
}
}
Using char * you might load all the image with one fread, thus avoiding the two for loops :)
fread(rev,witdh,height,fin);
In this way you may point each single pixel using:
rev[y*width+x];

Related

Memory Allocation of 3D Array and Use of fread in C results

// A part of Code
int dim1=height;
int dim2=width;
int dim3=3;
int k;
unsigned char *** image = (unsigned char ***)malloc(dim1*dim2*3);
for (i = 0; i< dim1; i++) {
image[i] = (unsigned char **)malloc(dim2*sizeof(unsigned char *));
for (j = 0; j < dim2; j++) {
image[i][j] = (unsigned char *)malloc(dim3*sizeof(unsigned char ));
}
}
// B part of Code
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
fread(&image[i][j][0],sizeof(unsigned char),1,fp);
fread(&image[i][j][1],sizeof(unsigned char),1,fp);
fread(&image[i][j][2],sizeof(unsigned char),1,fp);
}
}
As you can see from above I am trying to declare a 3d array that will contain the pixel information of a bmp image. The fp pointer is to a binary file that the data is contained there.
My question is how is it possible when I try to fread using dynamic memory allocation to get wrong results in image table (meaning a blank image is printed even though the rest of my code that i dont include here is correct).
On the other hand when i remove the A part of the Code and replace it with "unsigned char image[height][width][3]" it works.
So what am i doing wrong in the memory allocation or in the use of fread? Because obviously the problem is there.
In order to make it easier lets assume that the size is 252x252x3.
typedef struct
{
unsigned char R;
unsigned char G;
unsigned char B;
}RGB;
void *allocateReadImage(size_t width, size_t height, FILE *fi)
{
RGB (*picture)[width] = malloc(sizeof(*picture) * height);
if(picture && fi)
{
if(fread(picture, sizeof(*picture), height, fi) != height)
{
free(picture);
picture = NULL;
}
}
return picture;
}
usage:
RGB *mypicture = allocateReadImage(1600, 1200, inputfile);
if(!mypicture) { /*some error handling*/ }

Why is my code seg faulting when trying to extract the RGB components from a bmp file?

I am trying to extract the RGB components from a bmp file but I am getting a seg fault when it gets to Data[i][j].Blue. I try printing out the hex of the three colors and it prints them out good but then it prints out that all RGB components are 0xFF and then it seg faults when it gets to the blue. Any help I get is greatly appreciated.
int inputColors(char *filename, struct INFOHEADER *InfoHeader, struct PIXEL **Data){
int i = 0, j = 0;
FILE *inputFile;
printf("The height of the picture is %d\n", InfoHeader->Height);
printf("The width of the picture is %d\n", InfoHeader->Width);
if((inputFile = fopen(filename, "r")) == NULL){
printf("Unable to open .bmp file\n");
exit(1);
}
//Mallocing enough space for the 2D structures of pixels (colors)
Data = (struct PIXEL **)malloc(InfoHeader->Width * sizeof(struct PIXEL *));
for(i = 0; i < InfoHeader->Height; i++){
Data[i] = (struct PIXEL *)malloc(InfoHeader->Height * InfoHeader->Width * sizeof(struct PIXEL));
}
//This goes until after we are down with the header
fseek(inputFile, 54, SEEK_SET);
//Inputing the data into the malloced struct
i = 0;
for(i = 0; i < InfoHeader->Height; i++){
for(j = 0; j < InfoHeader->Width; j++){
Data[i][j].Red = getc(inputFile);
// printf("The Red componet is %X\n", Data[i][j].Red);
Data[i][j].Green = getc(inputFile);
// printf("The green componet is %X\n", Data[i][j].Green);
Data[i][j].Blue = getc(inputFile);
// printf("The blue componet is %X\n", Data[i][j].Blue);
}
}
fclose(inputFile);
return 0;
}
Well for starters, your first malloc uses
InfoHeader->Width * sizeof(struct PIXEL *)
But then you use InfoHeader->Height when iterating over the array. Because of this mismatch, If InfoHeader->Width is smaller than InfoHeader->Height, it will not allocate enough memory to perform the iteration, and it will SEGFAULT.
Data = (struct PIXEL **)malloc(InfoHeader->Width * sizeof(struct PIXEL *));
// ^^^^^
for(i = 0; i < InfoHeader->Height; i++){
// ^^^^^^
Data[i] = (struct PIXEL *)malloc(InfoHeader->Height * InfoHeader->Width * sizeof(struct PIXEL));
}

Rotating a ppm image 90 degrees to the right in C

I have the following problem with rotating the PPM image to the right
The first two lines in the result image are black (or some color from the rainbow)
Here's the code that sets the buffer for the image (the variables g_Width and g_height are set by a function)
struct pixel *image = malloc(sizeof(struct pixel) * g_width * g_height);
here's the function with the pointer passed into it
void rotate90(struct pixel *img) {
int i, j, size, th;
size = sizeof(struct pixel) * g_width * g_height;
struct pixel *buffer = malloc(size);
if (buffer == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < g_height; i++) {
for (j=0; j < g_width; j++) {
buffer[(g_height*j)+(g_height-i)] = img[(g_width*i) + j];
}
}
//copy the buffer into the image pointer
memcpy(img, buffer, size);
//free the buffer and swap the width and height around
free(buffer);
th = g_height;
g_height = g_width;
g_width = th;
}
If I print the image buffer it comes out just fine, but if I rotate it it comes out like this (note the first 2 lines of pixels)
https://www.dropbox.com/s/vh8l6s26enbxj42/t3.png?dl=0
it's as if the last 2 lines aren't being swapped at all, please help
EDIT: I solved the second black line at least, but I still need help with the
last line
As said you mix the first line (and overflow)
void rotate90(struct pixel *img) {
int i, j, size, th;
size = sizeof(struct pixel) * g_width * g_height;
struct pixel *buffer = malloc(size);
if (buffer == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < g_height; i++) {
for (j=0; j < g_width; j++) {
buffer[(g_height*j)+(g_height-i -- 1)] = img[(g_width*i) + j];
}
}
//copy the buffer into the image pointer
memcpy(img, buffer, size);
//free the buffer and swap the width and height around
free(buffer);
th = g_height;
g_height = g_width;
g_width = th;
}
This would rotate it one way (removing unnecessary brackets)
for (i=0; i<g_height; i++) {
for (j=0; j<g_width; j++) {
buffer[g_height * j + i] = img[g_width * i + j];
}
}
But your code suggest you want it the other way, and the code lacks a -1, resulting in clipping a line at one edge and an undefined line at the other edge.
for (i=0; i<g_height; i++) {
for (j=0; j<g_width; j++) {
buffer[g_height * j + g_height - i - 1] = img[g_width * i + j];
}
}

Storing pixel values of a BMP file

I'm trying to store the pixel values of a BMP file in a 2D dynamically allocated array of structs but it keeps giving a segmentation fault. Here's what I have so far:
#include <stdio.h>
#include <stdlib.h>
typedef struct PIXEL{
unsigned char Red, Green, Blue;
}*pixel;
int main (int argc, char *argv[])
{
//variable declarations and open the file
FILE* fin = fopen(argv[1], "rb");
if (fin == NULL){
printf("Error opening file.\n");
exit(0);
}
unsigned char info[54];
int width, height, i, j;
fread(info, sizeof(unsigned char), 54, fin); //read the header
width = *(int*)&info[18];
height = *(int*)&info[22];
pixel **image = (pixel **) malloc(sizeof(pixel *) * width); //reserve enough space for RGB for each pixel
for (i = 0; i < width; i++){
image[i] = (pixel *) malloc(sizeof(pixel) * height);
}
for (i = 0; i < width; i++){
for (j = 0; j < height; j++){
image[i][j]->Blue = getc(fin); //put the blue value of the pixel
image[i][j]->Green = getc(fin); //green value
image[i][j]->Red = getc(fin); //red value
printf("Pixel %d: [%d, %d, %d]\n", (i+1)*(j+1), image[i][j]->Blue, image[i][j]->Green, image[i][j]->Blue);
}
}
fclose(fin);
return 0;
}
You did not check for valid width and height values from the header. If for any reason they are huge (for instance if the file read failed) this will crash.
Also, %d in printf expects an int. You should cast your unsigned chars to int or it may crash.

Allocating memory to a 3-dimensional char array causes segmentation fault

As a spin of of an earlier question, I have run into some problems regarding allocating memory to a 3 dimensional array.
I am working on a project where we need to do some work on a text. To do this, we need to split the text into smaller sections, and process the text word for word. To save these smaller pieces of text, we have a 3D array, a list of sections each containing a list of the words in the section.
But I get a segmentation fault when I try to allocate memory for the individual words using malloc().
localText->list[i][n] = malloc(100 * sizeof(char));
Here is the entire code.
typedef struct {
char name[100];
char ***list;
}text;
int main(){
int i = 0, n, z,wordCount, sections;
FILE *file;
text *localText;
openFile(&file, "test.txt");
wordCount = countWords(file);
sections = (wordCount / 50) + 1;
localText = malloc(sizeof(text));
localText->list = malloc(sections * sizeof(char **));
for(i = 0; i < sections; i++)
localText->list[i] = malloc(50 * sizeof(char *));
for(n = 0; n < 50; n++)
localText->list[i][n] = malloc(100 * sizeof(char));
readFileContent(file, localText->list, 50);
freeText(localText);
return 1;
}
You're missing some braces:
for(i = 0; i < sections; i++) {
// ...
}

Resources