Ejemplo n.º 1
0
static bool handleRaw( rfbClient *c, int rx, int ry, int rw, int rh )
{
	int y=ry, h=rh;
	int bytesPerLine = rw * c->format.bitsPerPixel / 8;
	int linesToRead = RFB_BUFFER_SIZE / bytesPerLine;

	while( h > 0 )
	{
		if( linesToRead > h )
			linesToRead = h;

		if( !ReadFromRFBServer( c, c->buffer,bytesPerLine * linesToRead ) )
			return false;

		CopyRectangle( c, (uint8_t *)c->buffer, rx, y, rw,linesToRead );

		h -= linesToRead;
		y += linesToRead;
	}

	return true;
}
Ejemplo n.º 2
0
static rfbBool
HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh)
{
  rfbZlibHeader hdr;
  int remaining;
  int inflateResult;
  int toRead;

  /* First make sure we have a large enough raw buffer to hold the
   * decompressed data.  In practice, with a fixed BPP, fixed frame
   * buffer size and the first update containing the entire frame
   * buffer, this buffer allocation should only happen once, on the
   * first update.
   */
  if ( client->raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) {

    if ( client->raw_buffer != NULL ) {

      free( client->raw_buffer );

    }

    client->raw_buffer_size = (( rw * rh ) * ( BPP / 8 ));
    client->raw_buffer = (char*) malloc( client->raw_buffer_size );

  }

  if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbZlibHeader))
    return FALSE;

  remaining = rfbClientSwap32IfLE(hdr.nBytes);

  /* Need to initialize the decompressor state. */
  client->decompStream.next_in   = ( Bytef * )client->buffer;
  client->decompStream.avail_in  = 0;
  client->decompStream.next_out  = ( Bytef * )client->raw_buffer;
  client->decompStream.avail_out = client->raw_buffer_size;
  client->decompStream.data_type = Z_BINARY;

  /* Initialize the decompression stream structures on the first invocation. */
  if ( client->decompStreamInited == FALSE ) {

    inflateResult = inflateInit( &client->decompStream );

    if ( inflateResult != Z_OK ) {
      rfbClientLog(
              "inflateInit returned error: %d, msg: %s\n",
              inflateResult,
              client->decompStream.msg);
      return FALSE;
    }

    client->decompStreamInited = TRUE;

  }

  inflateResult = Z_OK;

  /* Process buffer full of data until no more to process, or
   * some type of inflater error, or Z_STREAM_END.
   */
  while (( remaining > 0 ) &&
         ( inflateResult == Z_OK )) {
  
    if ( remaining > RFB_BUFFER_SIZE ) {
      toRead = RFB_BUFFER_SIZE;
    }
    else {
      toRead = remaining;
    }

    /* Fill the buffer, obtaining data from the server. */
    if (!ReadFromRFBServer(client, client->buffer,toRead))
      return FALSE;

    client->decompStream.next_in  = ( Bytef * )client->buffer;
    client->decompStream.avail_in = toRead;

    /* Need to uncompress buffer full. */
    inflateResult = inflate( &client->decompStream, Z_SYNC_FLUSH );

    /* We never supply a dictionary for compression. */
    if ( inflateResult == Z_NEED_DICT ) {
      rfbClientLog("zlib inflate needs a dictionary!\n");
      return FALSE;
    }
    if ( inflateResult < 0 ) {
      rfbClientLog(
              "zlib inflate returned error: %d, msg: %s\n",
              inflateResult,
              client->decompStream.msg);
      return FALSE;
    }

    /* Result buffer allocated to be at least large enough.  We should
     * never run out of space!
     */
    if (( client->decompStream.avail_in > 0 ) &&
        ( client->decompStream.avail_out <= 0 )) {
      rfbClientLog("zlib inflate ran out of space!\n");
      return FALSE;
    }

    remaining -= toRead;

  } /* while ( remaining > 0 ) */

  if ( inflateResult == Z_OK ) {

    /* Put the uncompressed contents of the update on the screen. */
    CopyRectangle(client, (uint8_t *)client->raw_buffer, rx, ry, rw, rh);
  }
  else {

    rfbClientLog(
            "zlib inflate returned error: %d, msg: %s\n",
            inflateResult,
            client->decompStream.msg);
    return FALSE;

  }

  return TRUE;
}
Ejemplo n.º 3
0
static int HandleZRLETile(rfbClient* client,
                          uint8_t* buffer,size_t buffer_length,
                          int x,int y,int w,int h) {
    uint8_t* buffer_copy = buffer;
    uint8_t* buffer_end = buffer+buffer_length;
    uint8_t type;
#if BPP!=8
    uint8_t zywrle_level = (client->appData.qualityLevel & 0x80) ?
                           0 : (3 - client->appData.qualityLevel / 3);
#endif

    if(buffer_length<1)
        return -2;

    type = *buffer;
    buffer++;
    {
        if( type == 0 ) /* raw */
#if BPP!=8
            if( zywrle_level > 0 ) {
                CARDBPP* pFrame = (CARDBPP*)client->frameBuffer + y*client->width+x;
                int ret;
                client->appData.qualityLevel |= 0x80;
                ret = HandleZRLETile(client, buffer, buffer_end-buffer, x, y, w, h);
                client->appData.qualityLevel &= 0x7F;
                if( ret < 0 ) {
                    return ret;
                }
                ZYWRLE_SYNTHESIZE( pFrame, pFrame, w, h, client->width, zywrle_level, (int*)client->zlib_buffer );
                buffer += ret;
            } else
#endif
            {
#if REALBPP!=BPP
                int i,j;

                if(1+w*h*REALBPP/8>buffer_length) {
                    rfbClientLog("expected %d bytes, got only %d (%dx%d)\n",1+w*h*REALBPP/8,buffer_length,w,h);
                    return -3;
                }

                for(j=y*client->width; j<(y+h)*client->width; j+=client->width)
                    for(i=x; i<x+w; i++,buffer+=REALBPP/8)
                        ((CARDBPP*)client->frameBuffer)[j+i] = UncompressCPixel(buffer);
#else
                CopyRectangle(client, buffer, x, y, w, h);
                buffer+=w*h*REALBPP/8;
#endif
            }
        else if( type == 1 ) /* solid */
        {
            CARDBPP color = UncompressCPixel(buffer);

            if(1+REALBPP/8>buffer_length)
                return -4;

            FillRectangle(client, x, y, w, h, color);

            buffer+=REALBPP/8;

        }
        else if( (type >= 2)&&(type <= 127) ) /* packed Palette */
        {
            CARDBPP palette[16];
            int i,j,shift,
                bpp=(type>4?(type>16?8:4):(type>2?2:1)),
                mask=(1<<bpp)-1,
                divider=(8/bpp);

            if(1+type*REALBPP/8+((w+divider-1)/divider)*h>buffer_length)
                return -5;

            /* read palette */
            for(i=0; i<type; i++,buffer+=REALBPP/8)
                palette[i] = UncompressCPixel(buffer);

            /* read palettized pixels */
            for(j=y*client->width; j<(y+h)*client->width; j+=client->width) {
                for(i=x,shift=8-bpp; i<x+w; i++) {
                    ((CARDBPP*)client->frameBuffer)[j+i] = palette[((*buffer)>>shift)&mask];
                    shift-=bpp;
                    if(shift<0) {
                        shift=8-bpp;
                        buffer++;
                    }
                }
                if(shift<8-bpp)
                    buffer++;
            }

        }
        /* case 17 ... 127: not used, but valid */
        else if( type == 128 ) /* plain RLE */