fread reads incorrectly - negative 16 million for 2-byte read

This is a discussion on fread reads incorrectly - negative 16 million for 2-byte read within the C Programming forums, part of the General Programming Boards category; This doesn't make any sense. Why is fread returning -16 million when only 2 bytes are supposed to be read, ...

  1. #1
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582

    fread reads incorrectly - negative 16 million for 2-byte read

    This doesn't make any sense. Why is fread returning -16 million when only 2 bytes are supposed to be read, and only when the image's width is over 256 pixels. A 1024x85 image reads correctly, but 128x23 is returning -16 million for both width and height. Here's what I have (note: I'm reading a TGA file here):

    Code:
    ...
    			fseek(FileHandle, 12, SEEK_SET); // skip to the width and height part of a TGA image
    			MainData->Info.biSize = 40; // the size of the struct, always 40 in my case (due to true color being used)
    			fread(&MainData->Info.biWidth, 2, 1, FileHandle); // problem!
    			fread(&MainData->Info.biHeight, 2, 1, FileHandle); // problem!
    			MainData->Info.biPlanes = 1; // always 1
    			MainData->Info.biBitCount = 32; // number of bits per pixel, always to be 32 for TGA images (due to alpha channel)
    			MainData->Info.biCompression = BI_RGB; // no compression used
    			MainData->Info.biSizeImage = MainData->Info.biWidth*MainData->Info.biHeight*4; // problem (2.9 billion!?)
    			MainData->Info.biXPelsPerMeter = 2835; // resolution in pixels per meter - this can be anything
    			MainData->Info.biYPelsPerMeter = 2835;
    			MainData->Info.biClrUsed = 0; // always 0 in my case
    			MainData->Info.biClrImportant = 0; // same here
    			fseek(FileHandle, 18, SEEK_SET); // skip to the main image data
    			
    			fread(MainImageData, 1, MainData->Info.biSizeImage, FileHandle); // read the main image data // reads in BGRA format
    ...
    Why, for a 256x51 or 128x23 image (and other sizes with a width 256 pixels or less) am I getting negative 16 million for the width and height, when a 1024x85 has it read correctly? What's more is that I haven't even changed this part of the code in a very long time and it's worked just fine well beforehand. It's just now acting up and it's causing unhandled exceptions to occur (expected since 2.9 billion (yes, billion) bytes being changed in memory is bound to cause some byte my program doesn't have permission to change to change). Any ideas why this is happening? The pointers are fine (those, too, haven't been touched for a very long time (nearly a year even).
    Last edited by ulillillia; 02-25-2010 at 04:40 PM. Reason: subject expanded on
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  2. #2
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Code:
    fread(&MainData->Info.biWidth, 2, 1, FileHandle); // problem!
    fread(&MainData->Info.biHeight, 2, 1, FileHandle); // problem!
    What types are biWidth and biHeight? If they are 4-byte ints and you are only reading 2 bytes then the remaining 2 bytes are containing uninitialized (random) data. You can either zero out the struct before using it, or change width and height to a 2-byte type.

  3. #3
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,236
    Why the hell are you trying to load a TGA file using BMP format? The two are completely unrelated.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    TGA files use 2-byte data for the width and height elements. Interestingly, for years, I've had it like this, with numerous loads and reloads and this has never happened. Now that you've mentioned it, I think I know what I need to do - read one byte at a time then multiply the numbers out accordingly:

    Byte0+Byte1*256+Byte2*65536+Byte3*16777216

    TGA is stored big endian so that order works.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Quote Originally Posted by ulillillia View Post
    TGA files use 2-byte data for the width and height elements.
    I know.. What I meant is; what type are the variables in the struct?

    I think I know what I need to do - read one byte at a time then multiply the numbers out accordingly:

    Byte0+Byte1*256+Byte2*65536+Byte3*16777216
    Why would you read 4 bytes if it's a 2 byte field?

  6. #6
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    I was illustrating the concept which is why I went out to 4 bytes instead of 2. The biWidth elements in the struct are 4-byte "long" variables.

    However, I found the real problem: array overflow. One of the images was supposed to be 512x51, and the array was made big enough to account for that. I had an update to the image about a month ago, but noticed I saved it as 1024x51 instead (two repeats instead of 1) and thus fread was reading twice as much as it should've read which inevitably caused it to write values beyond what it should, triggering the unhandled exceptions once it got to one of the really big images. The first two of several images loaded perfectly fine, no problems, but oddly, the width on the third, after reading the main image data, was set to 0. The -16 million number was still present, in a later one but once I cropped the repeating image to the correct size, and replaced the old file with the fixed one, the problem was solved.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  7. #7
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    Quote Originally Posted by brewbuck View Post
    Why the hell are you trying to load a TGA file using BMP format? The two are completely unrelated.
    It's only the width, height, and image data that I need. Resolution, etc. are irrelevant. I use TGA files for any image needing 32-bit color, BMP files for any image needing 24-bit color since I don't need the alpha channel. I don't use anything else so in this way, it does work, and it has been for me for nearly 2 years....
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    @the "math wizard"

    It is not possible to fit 16000000 into a 2 byte data type, so something from your story is missing. This is like someone claiming they keep spilling a gallon of water out of their coffee cup.

    So I'm not sure why you continue to post about your problem, when, as Mike pointed out and anyone with half a brain would realize, you still have not included the information which would permit someone besides yourself to analyse the problem in a way that isn't just throwing darts blindfolded.

    If your purpose is to blog vaguely about programming woes, fine. Otherwise, just like everyone else, you might want to post the actual definition of your datatypes, etc. Nobody is going to assume this isn't just a stupid mistake in your code until you can show that it isn't.
    Last edited by MK27; 02-25-2010 at 08:31 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    biWidth is a 4-byte data type, as I've stated, of which can easily fit 16 million. The file reading was not the problem, it was array overflow, as stated as well, due to the image being unexpectedly larger than I thought (forgot to crop it from an update about 2 months ago). The data was being read correctly, from using the step-by-step debugger, but, read my reply 2 above yours (MK27) and you'll see what the culprit is and why it happened.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fread problems or memory problems
    By Lechuza in forum C Programming
    Replies: 1
    Last Post: 03-22-2009, 12:45 PM
  2. Why is fread sometimes taking so long?
    By manugarciac in forum C++ Programming
    Replies: 2
    Last Post: 04-28-2007, 11:25 PM
  3. Weird problem with fwrite() and fread()
    By piote in forum C Programming
    Replies: 2
    Last Post: 11-13-2004, 02:07 PM
  4. Replies: 6
    Last Post: 05-01-2003, 02:25 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21