Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Save QImage from BYTE buffer segfaults ?

Save QImage from BYTE buffer segfaults ?

Scheduled Pinned Locked Moved Solved General and Desktop
qimagebmpbytes
43 Posts 8 Posters 11.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mranger90M mranger90

    @R-P-H Of course it's black, the data never gets initialized.
    Also, the reason why it doesn't crash is because:
    BYTE *buf = new BYTE(x * y); // allocates a single byte, initialized to the value of (x * y)
    BYTE *buf = new BYTE[x * y]; // allocates an array of bytes whose size is x * y

    R Offline
    R Offline
    R-P-H
    wrote on last edited by
    #32

    @mranger90 said in Save QImage from BYTE buffer segfaults ?:

    @R-P-H Of course it's black, the data never gets initialized.
    Also, the reason why it doesn't crash is because:
    BYTE *buf = new BYTE(x * y); // allocates a single byte, initialized to the value of (x * y)
    BYTE *buf = new BYTE[x * y]; // allocates an array of bytes whose size is x * y

    The image is always black and it's not supposed to be, so this doesn't work.

    1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by hskoglund
      #33

      Hi, you could try explicitly specify the number of bytes per line:
      Edit: also, it could be that your deleting the buffer before the QImage is deleted:

      BYTE *buf = new BYTE(imWidth * imHeight);
      //Populate buf with data using API call here (not shown)
      {
          QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
          img.save("image.bmp", "BMP");
      }
      delete [] buf;
      
      R 1 Reply Last reply
      0
      • hskoglundH hskoglund

        Hi, you could try explicitly specify the number of bytes per line:
        Edit: also, it could be that your deleting the buffer before the QImage is deleted:

        BYTE *buf = new BYTE(imWidth * imHeight);
        //Populate buf with data using API call here (not shown)
        {
            QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
            img.save("image.bmp", "BMP");
        }
        delete [] buf;
        
        R Offline
        R Offline
        R-P-H
        wrote on last edited by
        #34

        @hskoglund said in Save QImage from BYTE buffer segfaults ?:

        Hi, you could try explicitly specify the number of bytes per line:
        Edit: also, it could be that your deleting the buffer before the QImage is deleted:

        BYTE *buf = new BYTE(imWidth * imHeight);
        //Populate buf with data using API call here (not shown)
        {
            QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
            img.save("image.bmp", "BMP");
        }
        delete [] buf;
        

        Hi, thanks for the suggestion. I tried it and result is the same...still crashes on occasion.

        I also tried with removing the delete [] buf line and still the same.

        B 1 Reply Last reply
        0
        • R R-P-H

          @hskoglund said in Save QImage from BYTE buffer segfaults ?:

          Hi, you could try explicitly specify the number of bytes per line:
          Edit: also, it could be that your deleting the buffer before the QImage is deleted:

          BYTE *buf = new BYTE(imWidth * imHeight);
          //Populate buf with data using API call here (not shown)
          {
              QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
              img.save("image.bmp", "BMP");
          }
          delete [] buf;
          

          Hi, thanks for the suggestion. I tried it and result is the same...still crashes on occasion.

          I also tried with removing the delete [] buf line and still the same.

          B Offline
          B Offline
          Bonnie
          wrote on last edited by
          #35

          @R-P-H
          If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
          As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
          So I won't be surprised that it crashes.

          R 1 Reply Last reply
          0
          • B Bonnie

            @R-P-H
            If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
            As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
            So I won't be surprised that it crashes.

            R Offline
            R Offline
            R-P-H
            wrote on last edited by
            #36

            @Bonnie said in Save QImage from BYTE buffer segfaults ?:

            @R-P-H
            If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
            As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
            So I won't be surprised that it crashes.

            I tried with new BYTE[imWidth * imHeight] as well but the image is always black.

            B 1 Reply Last reply
            0
            • R R-P-H

              @Bonnie said in Save QImage from BYTE buffer segfaults ?:

              @R-P-H
              If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
              As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
              So I won't be surprised that it crashes.

              I tried with new BYTE[imWidth * imHeight] as well but the image is always black.

              B Offline
              B Offline
              Bonnie
              wrote on last edited by Bonnie
              #37

              @R-P-H
              Right, this is another problem.
              How can you be sure your populated data is not all black?
              I will suggest you do some tests without Qt classes.

              BYTE *buf = new BYTE[imWidth * imHeight];
              //Populate buf with data using API call here (not shown)
              bool AllZero = true;
              for(int i = 0; i < imWidth * imHeight; i++) {
                  if(buf[i] != 0)
                      AllZero = false;
              }
              qDebug() << "AllZero :" << AllZero;
              delete [] buf;
              

              Or you can just print all of the data to see whether it is all zero(black).

              R 1 Reply Last reply
              0
              • B Bonnie

                @R-P-H
                Right, this is another problem.
                How can you be sure your populated data is not all black?
                I will suggest you do some tests without Qt classes.

                BYTE *buf = new BYTE[imWidth * imHeight];
                //Populate buf with data using API call here (not shown)
                bool AllZero = true;
                for(int i = 0; i < imWidth * imHeight; i++) {
                    if(buf[i] != 0)
                        AllZero = false;
                }
                qDebug() << "AllZero :" << AllZero;
                delete [] buf;
                

                Or you can just print all of the data to see whether it is all zero(black).

                R Offline
                R Offline
                R-P-H
                wrote on last edited by R-P-H
                #38

                @Bonnie said in Save QImage from BYTE buffer segfaults ?:

                @R-P-H
                Right, this is another problem.
                How can you be sure your populated data is not all black?
                I will suggest you do some tests without Qt classes.

                BYTE *buf = new BYTE[imWidth * imHeight];
                //Populate buf with data using API call here (not shown)
                bool AllZero = true;
                for(int i = 0; i < imWidth * imHeight; i++) {
                    if(buf[i] != 0)
                        AllZero = false;
                }
                qDebug() << "AllZero :" << AllZero;
                delete [] buf;
                

                Or you can just print all of the data to see whether it is all zero(black).

                Yes it's all black everytime.

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  R-P-H
                  wrote on last edited by
                  #39

                  I would like to try save the buffer to a
                  BMP image using only standard C++ just to check that it's not a problem with using QImage. But I haven't been able to get that working yet...

                  1 Reply Last reply
                  0
                  • hskoglundH Offline
                    hskoglundH Offline
                    hskoglund
                    wrote on last edited by
                    #40

                    QImage is quite reliable, for example if I add just 2 for loops to change the pixels to something not black:

                    int imWidth = 260;
                    int imHeight = 300;
                    
                    typedef unsigned char BYTE;
                    BYTE *buf = new BYTE[imWidth * imHeight];
                    
                    for (int y = 0; (y < imHeight); ++y)
                        for (int x = 0; (x < imWidth); ++x)
                            buf[x + y * imWidth] = x*x + y*y;
                    
                    QImage img(buf, imWidth, imHeight, QImage::Format_Grayscale8);
                    
                    img.save("image.bmp", "BMP");
                    delete [] buf;
                    

                    I get:
                    Screenshot 2020-07-10 at 01.49.14.png

                    R 1 Reply Last reply
                    1
                    • hskoglundH Offline
                      hskoglundH Offline
                      hskoglund
                      wrote on last edited by
                      #41

                      Hi again, dug around in my old projects (turn-of-the-century old :-) and I found this function to write grey BMP files the hard way:

                      void save_bitmap_grey8(char* file_name, int width, int height, BYTE* pixel_data)
                      {
                          #pragma pack(push, 1)
                          struct bitmap_file_header
                          {
                              short bitmap_type;
                              int   file_size;
                              short reserved1;
                              short reserved2;
                              int   offset_bits;
                          } bfh;
                          #pragma pack(pop)
                      
                          struct bitmap_image_header
                          {
                              int   size_header;
                              int   width;
                              int   height;
                              short planes;
                              short bit_count;
                              int   compression;
                              int   image_size;
                              int   ppm_x;
                              int   ppm_y;
                              int   clr_used;
                              int   clr_important;
                          } bih;
                      
                          struct grey_palette { BYTE r; BYTE g; BYTE b; BYTE a; } gp[256];
                          for (int i = 0; (i < 256); ++i)
                          {
                               gp[i].r = gp[i].g = gp[i].b = i;
                               gp[i].a = 0;
                          }
                      
                          int imagesize = height * (((width * 8 + 31) & ~31) / 8);
                      
                          memcpy(&bfh.bitmap_type, "BM", 2);
                          bfh.file_size   = sizeof(bfh) + sizeof(bih) + sizeof(gp) + imagesize;
                          bfh.reserved1   = 0;
                          bfh.reserved2   = 0;
                          bfh.offset_bits = sizeof(bfh) + sizeof(bih) + sizeof(gp);
                      
                          bih.size_header   = sizeof(bih);
                          bih.width         = width;
                          bih.height        = height;
                          bih.planes        = 1;
                          bih.bit_count     = 8;
                          bih.compression   = 0;
                          bih.image_size    = imagesize;
                          bih.ppm_x         = 3780; // meter->inch->96 ppi
                          bih.ppm_y         = 3780; // same here
                          bih.clr_used      = 256;
                          bih.clr_important = 256;
                      
                          FILE* image = fopen(file_name, "wb");
                          fwrite(&bfh, 1, sizeof(bfh), image);
                          fwrite(&bih, 1, sizeof(bih), image);
                          fwrite(&gp, 1, sizeof(gp), image);
                          fwrite(pixel_data, 1, width * height, image);
                      
                          fclose(image);
                      }
                      

                      So just swap out QImage with the above function, like this:

                      int imWidth = 260;
                      int imHeight = 300;
                      
                      BYTE *buf = new BYTE[imWidth * imHeight];
                      
                      for (int y = 0; (y < imHeight); ++y)
                          for (int x = 0; (x < imWidth); ++x)
                              buf[x + y * imWidth] = x*x + y*y;
                      
                      save_bitmap_grey8("image.bmp",imWidth,imHeight,buf);
                      
                      delete [] buf;
                      

                      Looks exactly the same, except....
                      Screenshot 2020-07-10 at 05.35.30.png it's upside down! That's a relic of OS/2's spec. for bitmaps, they wanted (x =0 , y = 0) to be in lower left corner instead of top left corner. QImage fixes this but my code has that vintage upside/down bug :-)

                      1 Reply Last reply
                      1
                      • hskoglundH hskoglund

                        QImage is quite reliable, for example if I add just 2 for loops to change the pixels to something not black:

                        int imWidth = 260;
                        int imHeight = 300;
                        
                        typedef unsigned char BYTE;
                        BYTE *buf = new BYTE[imWidth * imHeight];
                        
                        for (int y = 0; (y < imHeight); ++y)
                            for (int x = 0; (x < imWidth); ++x)
                                buf[x + y * imWidth] = x*x + y*y;
                        
                        QImage img(buf, imWidth, imHeight, QImage::Format_Grayscale8);
                        
                        img.save("image.bmp", "BMP");
                        delete [] buf;
                        

                        I get:
                        Screenshot 2020-07-10 at 01.49.14.png

                        R Offline
                        R Offline
                        R-P-H
                        wrote on last edited by
                        #42

                        @hskoglund Thanks for the info ! Looks to me like the API is not populating the buffer hence why it is all black.

                        1 Reply Last reply
                        0
                        • R Offline
                          R Offline
                          R-P-H
                          wrote on last edited by
                          #43

                          @mranger90 said in Save QImage from BYTE buffer segfaults ?:

                          try:
                          BYTE *buf = new BYTE[imWidth * imHeight];

                          So the issue turned out to be with the device itself. Changing the code as above and replacing the device solved the issue. Thanks.

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved