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 ?
QtWS25 Last Chance

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.
  • H hskoglund
    9 Jul 2020, 15:44

    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 9 Jul 2020, 16:20 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 9 Jul 2020, 16:35
    0
    • R R-P-H
      9 Jul 2020, 16:20

      @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 9 Jul 2020, 16:35 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 9 Jul 2020, 16:48
      0
      • B Bonnie
        9 Jul 2020, 16: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 Offline
        R Offline
        R-P-H
        wrote on 9 Jul 2020, 16:48 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 9 Jul 2020, 16:59
        0
        • R R-P-H
          9 Jul 2020, 16:48

          @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 9 Jul 2020, 16:59 last edited by Bonnie 7 Sept 2020, 17:12
          #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 9 Jul 2020, 21:09
          0
          • B Bonnie
            9 Jul 2020, 16:59

            @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 9 Jul 2020, 21:09 last edited by R-P-H 7 Sept 2020, 22:38
            #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 9 Jul 2020, 23:09 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
              • H Offline
                H Offline
                hskoglund
                wrote on 9 Jul 2020, 23:49 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 10 Jul 2020, 08:33
                1
                • H Offline
                  H Offline
                  hskoglund
                  wrote on 10 Jul 2020, 03:39 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
                  • H hskoglund
                    9 Jul 2020, 23:49

                    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 10 Jul 2020, 08:33 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 6 Aug 2020, 11:28 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