Thread: different data types

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    18

    different data types

    So I have a TIFF raster image, which is 1200x959. Using the libtiff library, I get its dimensions and store them in two variables, w (width) and h (height). But both of these are of type uint32, which I'm pretty sure is the same as unsigned long. I want to manipulate the data and store it in some 2d arrays (Red, Grn, Blu). To do this, I need some loops. So my first question is what does the compiler do when I write something like
    Code:
    for (i=0; i<h; i++)?
    How does it go about comparing i (which is int) and h? I guess I'm not really knowledgeable at all about the difference between various types, and how the computer deals with them.

    Here is my code
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    #include <tiffio.h>
    
    int main()
    {
        TIFF *tif;
        int i, j;
        uint32 w, h, z, npixels;
        uint32 *raster;
        
        tif = TIFFOpen("c:\\image1.tif", "r");
        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
        npixels = w * h;
        uint32 Red[h][w]; /*SEGFAULT HERE*/
        uint32 Grn[h][w];
        uint32 Blu[h][w];
        
        raster = (uint32*) _TIFFmalloc(npixels * sizeof(uint32));
        TIFFReadRGBAImage(tif, w, h, raster, 0); 
        for (i = 0; i<h; i++)
        {
            for (j = 0; j<w; j++)
            {
                z = raster[i*w + h];
                Red[i][j] = (z & 0xff);
                Grn[i][j] = (z>>8) & 0xff;
                Blu[i][j] = (z>>16) & 0xff;
            }
        }
        _TIFFfree(raster);
        TIFFClose(tif);
        
        return 0;
    }
    This segfaults, apparently on the line where I declare Red. I know I'm doing something wrong with types, but I'm not sure what. the function TIFFReadRGBAImage takes the image and puts it into raster. Each element of raster holds 4 bytes, One is the amount of Red, and one for Green and one for Blue, (and one for transparency, I think).
    Thanks for your time
    PS: I know I shouldn't declare Red, Grn, Blu dynamically like that, but I don't want to worry about using malloc and not being sure about my code for that also. I'll change it when everything else is fixed.
    Last edited by elliptic; 06-04-2006 at 11:27 PM.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    My guess would be that it would convert 'h' to an integer; therefore, you could lose data. That's only a guess, though.

  3. #3
    Awesomefaceradcore bivhitscar's Avatar
    Join Date
    Apr 2006
    Location
    Melbourne, Australia
    Posts
    210
    The problem causing the segfault is due to the fact that you cannot dynamically allocate memory to an array in the fashoin you are attempting. Look into the use of malloc, calloc and free functions to allocate memory to the arrays at runtime.
    it's ironic considerate rarity patron of love higher knowledge engulfs me...

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    18
    Thanks for the reply,bivhitscar, but I think under C99 you can declare arrays dynamically like that, though it isn't "standard." In any event, I've tested declaring them like that in another program, and it works out.

  5. #5
    Awesomefaceradcore bivhitscar's Avatar
    Join Date
    Apr 2006
    Location
    Melbourne, Australia
    Posts
    210
    Well, I'm not very familiar with VLAs, so I can't really say much about that. But it really does look like the problem to me. *shrug*

    [EDIT]
    Are you certain the segfault is on that line?
    Last edited by bivhitscar; 06-05-2006 at 12:21 AM.
    it's ironic considerate rarity patron of love higher knowledge engulfs me...

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    18
    Here is the readout from gdb.
    Code:
    $ gdb prog2
    ...a bunch of gdb stuff...
    (gdb) run
    Starting program: /usr/coding/prog2.exe
    
    Program received signal SIGSEGV, Segmentation fault
    0x004012e3 in probe()
    (gdb) bt
    #0  0x004012e3 in probe()
    #1  0x00118f50 in ?? ()
    #2 0x00401107 in main() at prog2.c:18
    I don't know if #0 or #1 mean anything, but line 18 is where I declare the array.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > int i, j;
    So make them the same type as your w and h

    > uint32 Red[h][w];
    4603200 == 1200x959x4
    That's over 12MB of stack space for those 3 variables!!!
    Many systems impose a limit on the amount of stack space a single process is allowed to use, or set a default size.
    Which system are you on?



    > I don't know if #0 or #1 mean anything,
    They're just counting the nesting level of function calls.
    You can navigate up and down the nested set of function calls to examine the state within any function currently in the call chain.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    18
    Thanks for your replies. I'm on Win2k, running cygwin. I have 256 MB memory, if that matters.
    Here's some results of messing around. If I comment out the insides of the inner loop, it still segfaults. If I change
    Code:
     uint32 Red[h][w]
    to
    Code:
     uint32 Red[959][1200]
    , and the same for the other arrays, it still segfaults. If I comment out the array declarations, it runs fine. Hope this helps
    Thanks for your time

  9. #9
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    As salem said you cannot allocate so much space on the stack. stackspace is usually limited to just a few Mb. Allocate the arrays on the heap
    Kurt

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    ... using malloc(). And don't forget to free the memory when you're done with it.

    Do you even need an array? The calculation looks simple enough that you could calculate it on-the-fly when you need a colour value.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    18
    Okay y'all were completely correct (I think). Here is my new code
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <tiffio.h>
    
    int main()
    {
        FILE *fp;
        fp = fopen("c:\\output.txt", "w");
        TIFF *tif;
        uint32 i;
        uint32 j;
        uint32 w, h, z, npixels;
        uint32 *raster;
        tif = TIFFOpen("c:\\image1.tif", "r");
        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
        npixels = w * h;
        uint32 **Red;
        Red = (uint32**) malloc(h*sizeof(uint32*));
        if (Red == NULL) printf("no memory");
        for (i=0;i<h;i++)
        {
            Red[i] = (uint32*) malloc(w*sizeof(uint32));
            if (Red[i] == NULL) printf("no memory");
        }
        
        raster = (uint32*) _TIFFmalloc(npixels * sizeof(uint32));
        if (raster == NULL) printf("no memory");
        TIFFReadRGBAImage(tif, w, h, raster, 0); 
        for (i = 0; i<h; i++)
        {
            for (j = 0; j<w; j++)
            {
                z = raster[i*w + h];
                Red[i][j] = (z & 0xff);
            }
        }
        
        for (i = 0; i<h; i++)
        {
            fprintf(fp, "\n");
            for (j = 0; j<w; j++)
            {
                fprintf(fp, "%u \n", Red[i][j]);
            }
        }
        _TIFFfree(raster);
        TIFFClose(tif);
        free(Red);
        fclose(fp);
        return 0;
    }
    I'm just doing things with Red to simplify matters.
    Now, when I open c:\output.txt, it should be 1200 lines (I think), but instead it is 4764, but I'm pretty sure this just refelcts a limitation of Notepad's maximum width. But there are little things that look like small boxes, or perhaps small 0's. I think this just is an artifact of printing in "%u" mode.
    So I think I'm good for now. But what I want to do is encapsulate the malloc() part in a function. I tried writing one that took a pointer as an argument and allocated memory for it, but that segfaulted. But I would prefer to write one that mimicked malloc, so I could call it by
    Code:
    Red = create(w*h*sizeof(uint32));
    or something like that. Does anyone have any tips?

  12. #12
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Use a function pointer.

    Although, if malloc() really does the work, I don't know why you'd want to hide that fact: people (including you) might mistake create() for something you wrote and forget to free() memory, for instance. It seems like you are complicating things for the sake of doing it.
    Last edited by whiteflags; 06-05-2006 at 04:14 PM.

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You shouldn't cast malloc(), which was probably mentioned earlier on.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  14. #14
    Registered User
    Join Date
    May 2006
    Posts
    18
    Is there any way I can find out how much memory my program is using while its running? I'm looking at the documentation for gdb, but not finding anything

  15. #15
    Awesomefaceradcore bivhitscar's Avatar
    Join Date
    Apr 2006
    Location
    Melbourne, Australia
    Posts
    210
    Am I making an ass of myself by asking what OS you're using?

    If it's windows just run it and look at your process in the task manager.

    Yes, I think I am going to look like an ass...


    [EDIT]

    Note to self: Read previous posts more thoroughly...
    it's ironic considerate rarity patron of love higher knowledge engulfs me...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Extending basic data types.
    By nempo in forum C++ Programming
    Replies: 23
    Last Post: 09-25-2007, 03:28 PM
  2. Replies: 4
    Last Post: 06-14-2005, 05:45 AM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM
  5. Using enumerated data types
    By SXO in forum C++ Programming
    Replies: 7
    Last Post: 09-04-2001, 06:26 PM