Ejemplo n.º 1
0
char *JpegCompressData(XImage *image, int level, int *compressed_size)
{
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;

  CARD8 *srcBuf;
  JSAMPROW rowPointer[1];

  int dy, w, h;

  *compressed_size = 0;

  /*
   * Initialize the image stuff
   */

  bitsPerPixel = image -> bits_per_pixel;
  bytesPerLine = image -> bytes_per_line;
  byteOrder = image -> byte_order;

  #ifdef TEST
  fprintf(stderr, "******JpegCompressData: Image byte order [%d] bitmap bit order [%d].\n",
              image -> byte_order, image -> bitmap_bit_order);

  fprintf(stderr, "******JpegCompressData: Bits per pixel [%d] bytes per line [%d].\n",
              bitsPerPixel, bytesPerLine);
  #endif

  redShift   = FindLSB(image -> red_mask)   - 1;
  greenShift = FindLSB(image -> green_mask) - 1;
  blueShift  = FindLSB(image -> blue_mask)  - 1;

  #ifdef TEST
  fprintf(stderr, "******JpegCompressData: Red mask [0x%lx] green mask [0x%lx] blue mask [0x%lx].\n",
              image -> red_mask, image -> green_mask, image -> blue_mask);

  fprintf(stderr, "******JpegCompressData: Red shift [%d] green shift [%d] blue shift [%d].\n",
              redShift, greenShift, blueShift);
  #endif

  redMax   = image -> red_mask   >> redShift;
  greenMax = image -> green_mask >> greenShift;
  blueMax  = image -> blue_mask  >> blueShift;

  #ifdef TEST
  fprintf(stderr, "******JpegCompressData: Red max [0x%x] green max [0x%x] blue max [0x%x].\n",
              redMax, greenMax, blueMax);
  #endif

  w = image -> width;
  h = image -> height;

  jpegBeforeBuf = image -> data;

  #ifdef DEBUG
  fprintf(stderr, "******JpegCompressData: Width [%d] height [%d] level [%d].\n",
              w, h, level);
  #endif

  if (bitsPerPixel == 1 ||
          bitsPerPixel == 8)
  {
    #ifdef PANIC
    fprintf(stderr, "******JpegCompressData: PANIC! Invalid bits per pixel [%d].\n",
                bitsPerPixel);
    #endif

    return NULL;
  }

  /*
   * Allocate space for one line of the
   * resulting image, 3 bytes per pixel.
   */

  #ifdef DEBUG
  fprintf(stderr, "******JpegCompressData: Allocating [%d] bytes for the scanline.\n",
              w * 3);
  #endif

  srcBuf = (CARD8 *) malloc(w * 3);

  if (srcBuf == NULL)
  {
    #ifdef PANIC
    fprintf(stderr, "******JpegCompressData: PANIC! Cannot allocate [%d] bytes.\n",
                w * 3);
    #endif

    return NULL;
  }

  rowPointer[0] = srcBuf;

  cinfo.err = jpeg_std_error(&jerr);

  jpeg_create_compress(&cinfo);

  cinfo.image_width = w;
  cinfo.image_height = h;
  cinfo.input_components = 3;
  cinfo.in_color_space = JCS_RGB;

  jpeg_set_defaults(&cinfo);
  jpeg_set_quality(&cinfo, jpegQuality[level], 1);

  /*
   * Allocate memory for the destination
   * buffer.
   */

  jpegCompBufSize = JPEG_DEST_SIZE(w, h);

  #ifdef TEST
  fprintf(stderr, "******JpegCompressData: Allocating [%d] bytes for the destination data.\n",
              jpegCompBufSize);
  #endif

  jpegCompBuf = malloc(jpegCompBufSize);

  if (jpegCompBuf == NULL)
  {
    #ifdef PANIC
    fprintf(stderr, "******JpegCompressData: PANIC! Error allocating [%d] bytes for the Jpeg data.\n",
                jpegCompBufSize);
    #endif

    return NULL;
  }

  JpegSetDstManager(&cinfo);

  jpeg_start_compress(&cinfo, 1);

  #ifdef DEBUG
  fprintf(stderr, "******JpegCompressedData: Initialization finished.\n");
  #endif

  for (dy = 0; dy < h; dy++)
  {
    PrepareRowForJpeg(srcBuf, dy, w);

    jpeg_write_scanlines(&cinfo, rowPointer, 1);

    if (jpegError != 0)
    {
      break;
    }
  }

  #ifdef DEBUG
  fprintf(stderr, "******JpegCompressedData: Compression finished. Lines handled [%d,%d]. Error is [%d].\n",
              dy, h, jpegError);
  #endif

  if (jpegError == 0)
  {
    jpeg_finish_compress(&cinfo);
  }

  jpeg_destroy_compress(&cinfo);

  free((char *) srcBuf);

  if (jpegError != 0)
  {
    #ifdef PANIC
    fprintf(stderr, "******JpegCompressedData: PANIC! Compression failed. Error is [%d].\n",
                jpegError);
    #endif

    free(jpegCompBuf);

    return NULL;
  }

  /*
   * Check the size of the resulting data.
   */

  if (jpegDstDataLen > 0)
  {
    /*
     * Save the image on disk to help with
     * the debug.
     */

    #ifdef DEBUG

    int i = 0;

    fprintf(stderr, "******JpegCompressedData: Compressed size [%d].\n",
                jpegDstDataLen);

    jpegId++;

    sprintf(jpegName, "jpeg%d", jpegId);

    jpegFile = fopen(jpegName, "w");

    for (i = 0; i < jpegDstDataLen; i++)
    {
      fprintf(jpegFile, "%c", *(jpegCompBuf + i));
    }

    fclose(jpegFile);

    #endif

    *compressed_size = jpegDstDataLen;

    return jpegCompBuf;
  }
  else
  {
    #ifdef PANIC
    fprintf(stderr, "******JpegCompressedData: PANIC! Invalid size of the compressed data [%d].\n",
                jpegDstDataLen);
    #endif

    free(jpegCompBuf);

    return NULL;
  }
}
Ejemplo n.º 2
0
int
vncEncodeUltra2::SendJpegRect(BYTE *src,BYTE *dst, int dst_size, int w, int h, int quality,rfbPixelFormat m_remoteformat)
{

  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;

  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);
  BYTE *srcBuf=NULL;

  cinfo.image_width = w;
  cinfo.image_height = h;
  cinfo.in_color_space = JCS_RGB;
  cinfo.input_components = 3;

#ifdef JCS_EXTENSIONS
  // Try to have libjpeg read directly from our native format
  if(m_remoteformat.bitsPerPixel==32) {
    int redShift, greenShift, blueShift;

    if(m_remoteformat.bigEndian) {
      redShift = 24 - m_remoteformat.redShift;
      greenShift = 24 - m_remoteformat.greenShift;
      blueShift = 24 - m_remoteformat.blueShift;
    } else {
      redShift = m_remoteformat.redShift;
      greenShift = m_remoteformat.greenShift;
      blueShift = m_remoteformat.blueShift;
    }

    if(redShift == 0 && greenShift == 8 && blueShift == 16)
      cinfo.in_color_space = JCS_EXT_RGBX;
    if(redShift == 16 && greenShift == 8 && blueShift == 0)
      cinfo.in_color_space = JCS_EXT_BGRX;
    if(redShift == 24 && greenShift == 16 && blueShift == 8)
      cinfo.in_color_space = JCS_EXT_XBGR;
    if(redShift == 8 && greenShift == 16 && blueShift == 24)
      cinfo.in_color_space = JCS_EXT_XRGB;

    if (cinfo.in_color_space != JCS_RGB) {
      srcBuf = src;
      cinfo.input_components = 4;
    }
  }
#endif

  jpeg_set_defaults(&cinfo);
  jpeg_set_quality(&cinfo, quality, TRUE);
  if(quality >= 96) cinfo.dct_method = JDCT_ISLOW;
  else cinfo.dct_method = JDCT_FASTEST;

   cinfo.comp_info[0].h_samp_factor = 2;
   cinfo.comp_info[0].v_samp_factor = 2;

  JpegSetDstManager(&cinfo, dst, dst_size);

  JSAMPROW *rowPointer = new JSAMPROW[h];
  for (int dy = 0; dy < h; dy++)
    rowPointer[dy] = (JSAMPROW)(&srcBuf[dy * w * 4]);

  jpeg_start_compress(&cinfo, TRUE);
  while (cinfo.next_scanline < cinfo.image_height)
  {
    jpeg_write_scanlines(&cinfo, &rowPointer[cinfo.next_scanline],
      cinfo.image_height - cinfo.next_scanline);
	if (jpegError)
			break;
  }

  if (!jpegError)
		jpeg_finish_compress(&cinfo);
  jpeg_destroy_compress(&cinfo);

  delete[] rowPointer;
  if (jpegError) return 0;
  return jpegDstDataLen;
}