We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
I am working on MCB2300 (with LPC2378 processor). I have written a small function that will read the values into a matrix. But when the control comes to fread it completely hangs up, nothing can be done. Below is the my function which is giving problem
void loadImage(FILE* arq, unsigned char** Matrix){ int i,j; unsigned char tmp; long pos = 51; fseek(arq,0,0); for (i=0; i<300; i++){ for (j=0; j<400; j++){ pos+= 3; fseek(arq,pos,0); fread(&tmp,3,1,arq); Matrix[i][j] = tmp; } } }
Its working fine in GNU C. But when I have tried to use the same code in Keil uVision4, its is not working. Please let me know how to sort this problem
fread, as the name suggests, reads from a file.
Do you have a file system?
You seem to have forgotten to tell us what file system support you have - this isn't MS-DOS where you always have an OS with file system support.
The filesystem here is FAT16
Yes, but FAT16 is just a description of how data is stored in the memory device.
But what implementation do you have?
What code is fread() expected to call to perform the task?
And what implementation of that file system do you have to support access to it by functions like fread ?
I am trying to store an image into matrix pixel by pixel. The above code is doing the same. First of all I am opening the image in read mode and passing its file pointer (arq) as reference to loadImage() function. In my code inside the loop, 300 and 400 are corresponds to dimensions of the image (height and width respectively). Initially I thought fread() is not working. But I have realised it is working fine. I have tried the code by changing the height (i.e 300). I have used 1 instead of 300 for i . It worked fine and the values are stored in the Matrix. I have increased the value step by step, it worked fine till the value of i in the code is 8 but later on it stucks from there onwards. I think it has something to do with heap size?? Please help to get rid of this problem
On what basis do you think that?
What have you done to confirm whether it is or not?
"Please help to get rid of this problem"
First, you need to determine what the problem actually is!
The declaration of Matrix looks suspicious:
unsigned char** Matrix
This is a pointer to a pointer (or array of pointers) to unsigned char. You probably wanted this to be a pointer to a two-dimensional array. Can you show us the call to this function and the types of arguments you pass to it?
fseek() and fread() does return results, but you never check them. So most probably, you don't check the result of your memory allocations either.
By the way - why do you think you need to perform a seek between each read? Isn't your fread call moving the file pointer forward the required amount?
But then again - why do you do a seek specifying the value 0 when your first read is 51+3 bytes into the file?
And since you are skipping the image header - how do you even know that the image have 3 bytes for each pixel?
And tmp is a unsigned character, having size 1. So why do you try to read 3 bytes in your fread? Where do you want to place the remaining two bytes? Haven't you considered the result of reading more data than tmp can store? What may happen to other data stored directly after tmp on the stack? Would that be good? Would that even make your program work as expected?
You say the code works with GNU C. But haven't you considered what happens if a different compiler moves some variables into registers, instead of keeping them on the stack? Are C programs built using different compilers really expected to behave identically when you do buffer overflow attacks on the variables?
Thanks very much for your reply.
My apologies for not determining problem properly.
I am trying to read a 24 bit map file where each pixel is represented with 24 bits (i mean 3 bytes) so I am reading 3 bytes. Let me also explain about tmp. In my code I am using a structure as below
typedef struct { unsigned char RGB[3]; }RGB;
The declaration for tmp and Matrix are as below
RGB **Matrix; RGB tmp;
All the pixels of the matrix are read perfectly. I have inserted a printf statement after read in the above code and all the image values are printed in right way. But problem comes when I am trying to store in the matrix. Infact I was unable to allocate memory for the matrix with required size. So I was unable to store. Here is the code for allocating matrix
createMatrix(){ RGB** Matrix; int i; Matrix = (RGB **) malloc (sizeof (RGB*) * height); if (Matrix == NULL){ printf("Memory is not available"); exit(0); } for (i=0;i<height;i++){ Matrix[i] = (RGB *) malloc (sizeof(RGB) * width); if (Matrix[i] == NULL){ printf("Memory is not available"); exit(0); } } }
What changes do I need to make here to ensure matrix with required size is created?
Thanks in advance
Perhaps you don't have enough heap. Try increasing heap size. It should be specified in your startup code. Besides, the way you allocate memory for your bitmap appears inefficient: 1) The type RGB is 3 bytes, but the compiler could add padding when working with arrays of RGB (sizeof(RGB) == 4). So this could increase memory usage to 4 bytes per one instance of RGB. 2) A bitmap is essentially a two-dimensional array. Yet you allocate memory for it row-by-row, storing pointers to rows in another array. This way the number of heap allocations is Nrows+1, which adds to memory usage since each heap allocation wastes some memory on bookkeeping. Instead, you should allocate one big chunk of memory for one two-dimensional array. Or even a three-dimensionsl array: unsigned char bitmap[height][width][3].
So the original code you posted with "tmp" variable wasn't really real code, since tmp was a char while your _real_ tmp was RGB? Never show "almost" real code.
So what goes wrong with your allocation? Does it exit after a failure? Or does it return, but you are unhappy with contents of Matrix? This time too, you don't seem to show full code. No return type shown. And you don't show how the function hands over Matrix at the end.
Do you get an error printout?
Note that exit() isn't a perfect function to use in an embedded application, since there are no operating system to return to. There are neither a desktop nor a command line. Depending on tools, you might get the code stuck in an infinite loop somewhere. Or maybe the application restarts by calling main again. Or maybe you get a watchdog reset. exit() may not even give the processor time to print any pending error message.
Note that RGB contains 3 bytes, but what is sizeof(RGB) with your compiler?
How much memory do you need? How much memory have you set up as heap? How far do you get in the allocation before it fails? How have you verified that your height and width really have the values you think they have?
The type RGB is 3 bytes, but the compiler could add padding when working with arrays of RGB (sizeof(RGB) == 4). So this could increase memory usage to 4 bytes per one instance of RGB.
I have verified the sizeof(RGB) when memory is allocated by giving a printf statement. Always it is showing as 3 bytes only. So here no padding is done by compiler.
I have already tried previously by allocating one big chunk of memory for a three-dimensionsl array: unsigned char bitmap[height][width][3]. Even it did n't worked. In my application height and width are 320 and 240. But matrix with these values in not working. If height and width are very small values like 10,10 then it is working. But not for larger values
So what goes wrong with your allocation? Does it exit after a failure? Or does it return
It exits after failure.
sizeof(RGB) in my code is 3 bytes. In my application I am trying to read an image with 320 x 240 size. In my startup code heap is set as Heap_Size EQU 0x00000800 and if I try to change these values .\Obj\Memory.axf: Error: L6406W: No space in execution regions with .ANY selector matching Section
If I am taking an image with 10x8 dimensions it is working but beyond that it does n't.
How have you verified that your height and width really have the values you think they have?
Yes I have have verified. They have actual values (I mean height and width of input image)
If height and width are very small values like 10,10 then it is working. But not for larger values
How much RAM do you have allocated for the heap? Do you have enough RAM for this? 320x240x3 = 225 Kbytes.