Search code examples
c++mfcopengl-3libjpeg

WriteJPGBuffer method using libjpeg libraries instead of ijl15.lib


We have following method implemented using ijl15.lib API. We want to use libjpeg libraries instead of ijl. How should I implement WriteJPGBuffer using libjpeg libraries? We are aware of LoadJPG and SaveJPG from file. However i want to write and read the jpg image in buffer using libjpeg libraries. Any inputs will be very helpul. Thank you in advance.

   unsigned char WriteJPGBuffer(unsigned int &size)
    {
      size = 0;
      int jErr;
      JPEG_CORE_PROPERTIES jpgProps;
      bool colorsSwapped;

      if (!jpgSupported)  
        return NULL;

      jErr = ijlInit(&jpgProps);
      if (jErr != IJL_OK)
        return NULL;


      jpgProps.DIBWidth = m_width;
      jpgProps.DIBHeight = -m_height;
      jpgProps.DIBBytes = (unsigned char *)m_pData;
      jpgProps.DIBPadBytes = 0 ;     
      jpgProps.DIBChannels = 4;
      jpgProps.DIBColor = IJL_RGB;

      jpgProps.JPGFile = NULL;
      jpgProps.JPGWidth = m_width;
      jpgProps.JPGHeight = m_height;
      jpgProps.JPGChannels = 3;
      jpgProps.JPGColor = IJL_YCBCR;
      jpgProps.JPGSubsampling = IJL_411;
      jpgProps.jquality = jpgQuality;   
      unsigned int iSize = m_width*m_height*3;
      unsigned char * pBuffer = new unsigned char[iSize];
      jpgProps.JPGSizeBytes = iSize;
      jpgProps.JPGBytes = pBuffer;

      jpgProps.jprops.jpeg_comment_size = (unsigned short)m_strCommentAdobe.length;
      jpgProps.jprops.jpeg_comment = (char*)m_strCommentAdobe;

      colorsSwapped = SetInternalFormat(RGB);

      jErr = ijlWrite(&jpgProps, IJL_JBUFF_WRITEWHOLEIMAGE);

      if (colorsSwapped)
        SetInternalFormat(BGR);

      if (jErr != IJL_OK)
      {
        ijlFree(&jpgProps);
        return NULL;
      }

      size = jpgProps.JPGSizeBytes;

      ijlFree(&jpgProps);

      return jpgProps.JPGBytes;
    }

Solution

  • Thanks for your inputs. I have implemented the solution below through RND. In below implementation, we have image data stored in the class member variable in the form of RGBQUAD which i am converting into unsigned char* first using ConversionfromGLRGBQUADToUnsignedChar function and then writing it jpeg buffer.

    void ConversionfromGLRGBQUADToUnsignedChar(unsigned char* dataInCharFromGLRGBQUAD)
    {
        int spot,spotDst;
        for (int y = 0;y < m_height;y++)
        {
            for (int x = 0;x<m_width;x++)
            {
                spot = y * m_width + x;
                spotDst = spot * 3;
                dataInCharFromGLRGBQUAD[spotDst] = m_pData[spot].red;
                dataInCharFromGLRGBQUAD[spotDst + 1] = m_pData[spot].green;
                dataInCharFromGLRGBQUAD[spotDst + 2] = m_pData[spot].blue;
            }
        }
    }
    
    
    
    unsigned char * WriteJPGBuffer(unsigned int &size)
        {
           size = 0;
           struct jpeg_compress_struct cinfo;
           struct jpeg_error_mgr jerr;
           JSAMPROW row_pointer[1];
           unsigned char* dataInCharFromGLRGBQUAD;
           bool colorsSwapped;
           int row_stride;
    
           cinfo.err = jpeg_std_error(&jerr);
           jpeg_create_compress(&cinfo);
    
           unsigned long sizeOfJPGBuffer = 0;
    
           jpeg_mem_dest(&cinfo, &m_pDIBData, &sizeOfJPGBuffer);
    
           cinfo.image_width = m_width;
           cinfo.image_height = m_height;
           cinfo.input_components = 3;
           cinfo.in_color_space = JCS_RGB;
    
           cinfo.jpeg_color_space = JCS_YCbCr;
    
           jpeg_set_defaults(&cinfo);
           jpeg_set_quality(&cinfo, jpgQuality, true);
           jpeg_start_compress(&cinfo, true);
    
           colorsSwapped = SetInternalFormat(RGB);
    
           FlipVert();
    
           dataInCharFromGLRGBQUAD = new unsigned char[m_width*m_height*3];
           ConversionfromGLRGBQUADToUnsignedChar(dataInCharFromGLRGBQUAD);
    
           row_stride = cinfo.image_width * cinfo.input_components;
    
           while (cinfo.next_scanline < cinfo.image_height) 
           {
                row_pointer[0] = &dataInCharFromGLRGBQUAD[cinfo.next_scanline * row_stride];
                jpeg_write_scanlines(&cinfo, row_pointer, 1);
           }
    
           if (colorsSwapped)
               SetInternalFormat(BGR);
    
           jpeg_finish_compress(&cinfo);
           jpeg_destroy_compress(&cinfo);
    
           size = sizeOfJPGBuffer;
           delete[] dataInCharFromGLRGBQUAD;
    
           return m_pDIBData;
        }