Пример #1
0
int
process_switchB(ea_t curr, ea_t start, ea_t func_end)
{
  ea_t diff = start - curr, 
       min = func_end,
       ptr;
  unsigned long i;

  if ( diff && diff < 4 )
  {
    do_unknown_range(curr, diff, true);
  }
#ifdef PIC_DEBUG
 RP_TRACE2("start %X, to %X\n", start, func_end);
#endif
  ptr = get_next_code(start);
  if ( NULL == ptr )
   do_unknown(start,false);
  else
  {
   if ( isTail(getFlags(start)) )
   {
     do_unknown(prev_not_tail(start),false);
   }
   else
     do_unknown_range(start, ptr-start, true);
  }
  for ( i = 0; start+i < min; i += 4 )
  {
    ptr = got_addr - get_long(start + i);
#ifdef PIC_DEBUG
 RP_TRACE3("min is %X, ptr %X, i %d\n", min, ptr, i);
#endif
    if ( ptr < func_end )
    {
      if ( ptr < min )
        min = ptr;
#ifdef PIC_DEBUG
 RP_TRACE2("one_switch_entry %X, ptr %X\n", start+i, ptr );
#endif
      one_switch_entry(start+i, ptr);
    } else
     break; /* end ? */
  }
  return (i>>2);
}
Пример #2
0
ILboolean GifGetData(ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, GFXCONTROL *Gfx)
{
	ILubyte	*sp;
	ILint	code, fc, oc;
	ILubyte	DisposalMethod = 0;
	ILint	c, size;
	ILuint	i = 0, Read = 0;

	if (!Gfx->Used)
		DisposalMethod = (Gfx->Packed & 0x1C) >> 2;

	if((size = igetc()) == IL_EOF)
		return IL_FALSE;

	if (size < 2 || 9 < size) {
		return IL_FALSE;
	}

	stack  = (ILubyte*)ialloc(MAX_CODES + 1);
	suffix = (ILubyte*)ialloc(MAX_CODES + 1);
	prefix = (ILshort*)ialloc(sizeof(*prefix) * (MAX_CODES + 1));
	if (!stack || !suffix || !prefix) {
		ifree(stack);
		ifree(suffix);
		ifree(prefix);
		return IL_FALSE;
	}

	curr_size = size + 1;
	top_slot = 1 << curr_size;
	clear = 1 << size;
	ending = clear + 1;
	slot = newcodes = ending + 1;
	navail_bytes = nbits_left = 0;
	oc = fc = 0;
	sp = stack;
	success = IL_TRUE;

	while ((c = get_next_code()) != ending && Read < Height) {
		if (c == clear) {
			curr_size = size + 1;
			slot = newcodes;
			top_slot = 1 << curr_size;
			while ((c = get_next_code()) == clear);
			if (c == ending)
				break;
			if (c >= slot)
				c = 0;
			oc = fc = c;

			if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == c && (Gfx->Packed & 0x1) != 0)
				i++;
			else
				Data[i++] = c;

			if (i == Width) {
				Data += Stride;
				i = 0;
				Read += 1;
			}
		}
		else {
			code = c;
			if (code >= slot) {
				code = oc;
				*sp++ = fc;
			}
			while (code >= newcodes) {
				*sp++ = suffix[code];
				code = prefix[code];
			}
			*sp++ = (ILbyte)code;
			if (slot < top_slot) {
				fc = code;
				suffix[slot]   = fc;
				prefix[slot++] = oc;
				oc = c;
			}
			if (slot >= top_slot && curr_size < 12) {
				top_slot <<= 1;
				curr_size++;
			}
			while (sp > stack) {
				sp--;

				if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == *sp && (Gfx->Packed & 0x1) != 0)
					i++;
				else
					Data[i++] = *sp;

				if (i == Width) {
					Data += Stride;
					i = 0;
					Read += 1;
				}
			}
		}

	}

	ifree(stack);
	ifree(suffix);
	ifree(prefix);

	return success;
}
Пример #3
0
static short decoder(
		      short linewidth,
		      unsigned char far * buf,
		      unsigned char far * stack,
		      unsigned char far * suffix,
		      unsigned short far * prefix)
{
	unsigned char far *sp;
	unsigned char far *bufptr;
	register short code, fc, oc, bufcnt;
	short c, size, ret;

	/*
	 * Initialize for decoding a new image...
	 */
	if ((size = gif_get_byte()) < 0)
		return (size);
	if (size < 2 || 9 < size)
		return (BAD_CODE_SIZE);
	init_exp(size);

	/*
	 * Initialize in case they forgot to put in a clear code. (This
	 * shouldn't happen, but we'll try and decode it anyway...)
	 */
	oc = fc = 0;


	/*
	 * Set up the stack pointer and decode buffer pointer
	 */
	sp = stack;
	bufptr = buf;
	bufcnt = linewidth;

	/*
	 * This is the main loop.  For each code we get we pass through the
	 * linked list of prefix codes, pushing the corresponding "character"
	 * for each code onto the stack.  When the list reaches a single
	 * "character" we push that on the stack too, and then start
	 * unstacking each character for output in the correct order. Special
	 * handling is included for the clear code, and the whole thing ends
	 * when we get an ending code.
	 */
	while ((c = get_next_code()) != ending)
	{

		/*
		 * If we had a file error, return without completing the
		 * decode
		 */
		if (c < 0)
		{
			return (c);
		}

		/*
		 * If the code is a clear code, reinitialize all necessary
		 * items.
		 */
		if (c == clear)
		{
			curr_size = size + 1;
			slot = newcodes;
			top_slot = 1 << curr_size;

			/*
			 * Continue reading codes until we get a non-clear
			 * code (Another unlikely, but possible case...)
			 */
			while ((c = get_next_code()) == clear)
				;

			/*
			 * If we get an ending code immediately after a clear
			 * code (Yet another unlikely case), then break out
			 * of the loop.
			 */
			if (c == ending)
				break;

			/*
			 * Finally, if the code is beyond the range of
			 * already set codes, (This one had better NOT
			 * happen...  I have no idea what will result from
			 * this, but I doubt it will look good...) then set
			 * it to color zero.
			 */
			if (c >= slot)
				c = 0;

			oc = fc = c;

			/*
			 * And let us not forget to put the char into the
			 * buffer... And if, on the off chance, we were
			 * exactly one pixel from the end of the line, we
			 * have to send the buffer to the gif_out_line()
			 * routine...
			 */
			*bufptr++ = c;
			if (--bufcnt == 0)
			{
				if ((ret = gif_out_line(buf, linewidth)) < 0)
				{
					return (ret);
				}
				bufptr = buf;
				bufcnt = linewidth;
			}
		}
		else
		{

			/*
			 * In this case, it's not a clear code or an ending
			 * code, so it must be a code code...  So we can now
			 * decode the code into a stack of character codes.
			 * (Clear as mud, right?)
			 */
			code = c;

			/*
			 * Here we go again with one of those off chances...
			 * If, on the off chance, the code we got is beyond
			 * the range of those already set up (Another thing
			 * which had better NOT happen...) we trick the
			 * decoder into thinking it actually got the last
			 * code read. (Hmmn... I'm not sure why this works...
			 * But it does...)
			 */
			if (code >= slot)
			{
				if (code > slot)
					++bad_code_count;
				code = oc;
				*sp++ = fc;
			}

			/*
			 * Here we scan back along the linked list of
			 * prefixes, pushing helpless characters (ie.
			 * suffixes) onto the stack as we do so.
			 */
			while (code >= newcodes)
			{
				*sp++ = suffix[code];
				code = prefix[code];
			}

			/*
			 * Push the last character on the stack, and set up
			 * the new prefix and suffix, and if the required
			 * slot number is greater than that allowed by the
			 * current bit size, increase the bit size.  (NOTE -
			 * If we are all full, we *don't* save the new suffix
			 * and prefix...  I'm not certain if this is
			 * correct... it might be more proper to overwrite
			 * the last code...
			 */
			*sp++ = code;
			if (slot < top_slot)
			{
				suffix[slot] = fc = code;
				prefix[slot++] = oc;
				oc = c;
			}
			if (slot >= top_slot)
				if (curr_size < 12)
				{
					top_slot <<= 1;
					++curr_size;
				}

			/*
			 * Now that we've pushed the decoded string (in
			 * reverse order) onto the stack, lets pop it off and
			 * put it into our decode buffer...  And when the
			 * decode buffer is full, write another line...
			 */
			while (sp > stack)
			{
				*bufptr++ = *(--sp);
				if (--bufcnt == 0)
				{
					if ((ret = gif_out_line(buf, linewidth)) < 0)
					{
						return (ret);
					}
					bufptr = buf;
					bufcnt = linewidth;
				}
			}
		}
	}
	ret = 0;
	if (bufcnt != linewidth)
		ret = gif_out_line(buf, (linewidth - bufcnt));
	return (ret);
}
Пример #4
0
int main(int argc, char **argv) {
    struct option long_options[] = { { "gpio", 1, 0, 0 },
        { "address", 1, 0, 0 }, { "command", 1, 0, 0 }, { NULL, 0, 0, 0 } };
    unsigned char key;
    unsigned short address = 0;
    unsigned short code = 0;
    long int a2i;
    int gpio = -1, i, c;
    char command = UNKNOWN;
    char *progname, *end;

    if (setuid(0)) {
        perror("setuid");
        return -1;
    }

    while (1) {
        c = getopt_long(argc, argv, "", long_options, &i);
        if (c == -1)
            break;
        switch (c) {
            case 0:
                if (strcmp(long_options[i].name, "gpio") == 0) {
                    a2i = strtol(optarg, &end, 10);
                    if (errno == ERANGE && (a2i == LONG_MAX || a2i == LONG_MIN)) {
                        break;
                    }
                    gpio = a2i;
                } else if (strcmp(long_options[i].name, "address") == 0) {
                    a2i = strtol(optarg, &end, 10);
                    if (errno == ERANGE && (a2i == LONG_MAX || a2i == LONG_MIN)) {
                        break;
                    }
                    address = a2i;
                } else if (strcmp(long_options[i].name, "command") == 0) {
                    command = get_command_char(optarg);
                }
                break;
            default:
                usage(argv[0]);
        }
    }

    if (command == UNKNOWN || address == 0 || gpio == -1) {
        usage(argv[0]);
    }

    // store pid and lock it
    store_pid();

    srand(time(NULL));
    key = rand() % 255;

    if (wiringPiSetup() == -1) {
        fprintf(stderr, "Wiring Pi not installed");
        return -1;
    }

    openlog("srts", LOG_PID | LOG_CONS, LOG_USER);

    progname = basename(argv[0]);

    code = get_next_code(progname, address);
    syslog(LOG_INFO, "remote: %d, command: %d, code: %d\n", address, command,
           code);
    closelog();

    piHiPri (99);
    pinMode(gpio, OUTPUT);
    srts_transmit(gpio, key, address, command, code, 0);

    c = 7;
    if (command == PROG) {
        c = 20;
    }

    for (i = 0; i < c; i++) {
        srts_transmit(gpio, key, address, command, code, 1);
    }
    store_code(progname, address, code);

    return 0;
}
Пример #5
0
ILboolean GifGetData(ILimage *Image, ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, ILuint PalOffset, GFXCONTROL *Gfx)
{
	ILubyte	*sp;
	ILint	code, fc, oc;
	ILubyte	DisposalMethod = 0;
	ILint	c, size;
	ILuint	i = 0, Read = 0, j = 0;
	ILubyte	*DataPtr = Data;

	if (!Gfx->Used)
		DisposalMethod = (Gfx->Packed & 0x1C) >> 2;
	if((size = igetc()) == IL_EOF)
		return IL_FALSE;

	if (size < 2 || 9 < size) {
		return IL_FALSE;
	}

	stack  = (ILubyte*)ialloc(MAX_CODES + 1);
	suffix = (ILubyte*)ialloc(MAX_CODES + 1);
	prefix = (ILshort*)ialloc(sizeof(*prefix) * (MAX_CODES + 1));
	if (!stack || !suffix || !prefix)
	{
		cleanUpGifLoadState();
		return IL_FALSE;
	}

	curr_size = size + 1;
	top_slot = 1 << curr_size;
	clear = 1 << size;
	ending = clear + 1;
	slot = newcodes = ending + 1;
	navail_bytes = nbits_left = 0;
	oc = fc = 0;
	sp = stack;

	while ((c = get_next_code()) != ending && Read < Height) {
		if (c == clear)
		{
			curr_size = size + 1;
			slot = newcodes;
			top_slot = 1 << curr_size;
			while ((c = get_next_code()) == clear);
			if (c == ending)
				break;
			if (c >= slot)
				c = 0;
			oc = fc = c;

			if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == c && (Gfx->Packed & 0x1) != 0)
				i++;
			else if (i < Width)
				DataPtr[i++] = c + PalOffset;

			if (i == Width)
			{
				DataPtr += Stride;
				i = 0;
				Read += 1;
                ++j;
                if (j >= Height) {
                   cleanUpGifLoadState();
                   return IL_FALSE;
                }
			}
		}
		else
		{
			code = c;
            //BG-2007-01-10: several fixes for incomplete GIFs
			if (code >= slot)
			{
				code = oc;
                if (sp >= stack + MAX_CODES) {
                   cleanUpGifLoadState();
                   return IL_FALSE;
                }
                *sp++ = fc;
			}

            if (code >= MAX_CODES)
                return IL_FALSE; 
                while (code >= newcodes)
				{
                    if (sp >= stack + MAX_CODES)
					{
                        cleanUpGifLoadState();
                        return IL_FALSE;
                    }
                    *sp++ = suffix[code];
                    code = prefix[code];
                }
            
                if (sp >= stack + MAX_CODES) {
                cleanUpGifLoadState();
                return IL_FALSE;
            }

            *sp++ = (ILbyte)code;
			if (slot < top_slot)
			{
				fc = code;
				suffix[slot]   = fc;
				prefix[slot++] = oc;
				oc = c;
			}
			if (slot >= top_slot && curr_size < 12)
			{
				top_slot <<= 1;
				curr_size++;
			}
			while (sp > stack)
			{
				sp--;
				if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == *sp && (Gfx->Packed & 0x1) != 0)
					i++;
				else if (i < Width)
					DataPtr[i++] = *sp + PalOffset;

				if (i == Width)
				{
					i = 0;
					Read += 1;
                    j = (j+1) % Height;
					// Needs to start from Data, not Image->Data.
					DataPtr = Data + j * Stride;
				}
			}
		}
	}
	cleanUpGifLoadState();
	return IL_TRUE;
}
Пример #6
0
// Decode a single DU within an MCU
int decode_du(byte id_component)
{
    word bit_string = 0;
    byte cur_code = 0;
    
    memset(iceenv.block, 0, sizeof(int) * 64);
    
    jpeg_huffman_table cur_table = iceenv.huff_dc[UPR4(iceenv.components[id_component].id_dht)];
    
    cur_code = get_next_code(cur_table);
    
#ifdef _JPEG_DEBUG
    printf("Code found: %X\n", cur_code);
#endif
    
    bit_string = fetch_bits(cur_code);
    
#ifdef _JPEG_DEBUG
    printf("Bits fetched: %d\n", bit_string);
#endif
    
    short value = get_signed_short(bit_string, cur_code);
    
	iceenv.components[id_component].prev_dc += value;
    //mcu->dus[id_component][(y*samp_x) + x][0] = cur_mcu > 0 ? (mcus[cur_mcu - 1].dus[id_component][(y*samp_x) + x][0] + dc_value) : dc_value;
	iceenv.block[0] = iceenv.components[id_component].prev_dc;
    
#ifdef _JPEG_DEBUG
    printf("DC value: %d, absolute value: %d\n", block[0], value);
#endif
    
    // Dequantize DC value
	iceenv.block[0] *= iceenv.qt_tables[iceenv.components[id_component].qt_table][0];
    
    // Switch to AC table
    cur_table = iceenv.huff_ac[LWR4(iceenv.components[id_component].id_dht)];
    
    byte block_index = 1;
    
    int had_eob = 0;
    
    while (block_index < 64)
    {
        cur_code = get_next_code(cur_table);
        
        if (cur_code == 0)
        {
#ifdef _JPEG_DEBUG
    printf("\tEOB encountered\n");
#endif
            had_eob = 1;
            break;
        }
        
#ifdef _JPEG_DEBUG
    printf("\tSkipping %d zeros\n", (cur_code & 0xF0) >> 4);
#endif
        
        // Skip zeros
        block_index += UPR4(cur_code);
        if (block_index > 63)
            break;
        
        bit_string = fetch_bits(LWR4(cur_code));
        
#ifdef _JPEG_DEBUG
    printf("Fetched %d bits\n", cur_code & 0xF);
#endif
        
        value = get_signed_short(bit_string, LWR4(cur_code));
        
#ifdef _JPEG_DEBUG
    printf("AC value: %d\n", value);
#endif
        
        byte actual_index = jpeg_zzright[block_index];
        
        
        // Dequantize and unzigzag at the same time
		iceenv.block[actual_index] = value * iceenv.qt_tables[iceenv.components[id_component].qt_table][block_index];
        block_index++;
        
#ifdef _JPEG_DEBUG
    printf("Dequantized AC value: %d\n", block[actual_index]);
#endif
    }
    
    if (block_index > 64)
    {
        printf("CAUTION: Too many coefs in MCU [%d,%d]\n", iceenv.cur_mcu_x, iceenv.cur_mcu_y);
        getc(stdin);
    }
    
#ifdef _JPEG_DEBUG
    printf("\n");
#endif
    
    /****************************************************/
    /* Perform IDCT                                     */
    /****************************************************/
    int rowscols;
    for (rowscols = 0; rowscols < 8; rowscols++)
    {
        idctrow(&iceenv.block[8 * rowscols]);
    }
    for (rowscols = 0; rowscols < 8; rowscols++)
    {
        int targetPos = ((iceenv.cur_mcu_y * (iceenv.components[id_component].sy << 3) + (iceenv.cur_du_y << 3)) * iceenv.components[id_component].stride) + (iceenv.cur_mcu_x * (iceenv.components[id_component].sx << 3) + (iceenv.cur_du_x << 3));
        idctcol(&iceenv.block[rowscols], &iceenv.components[id_component].pixels[targetPos + rowscols], iceenv.components[id_component].stride);
    }
    
    return ERR_OK;
}
Пример #7
0
ILboolean GifGetData(ILimage *Image, ILubyte *Data, ILuint ImageSize, 
   ILuint OffX, ILuint OffY, ILuint Width, ILuint Height, ILuint Stride, 
   GFXCONTROL *Gfx)
{
	GifLoadState state;
	ILint	code, fc, oc;
	ILubyte	DisposalMethod = 0;
	ILint	c, size;
	ILuint	x = OffX, Read = 0, y = OffY;
	ILuint dataOffset = y * Stride + x;

	state.navail_bytes = 0;
	state.nbits_left = 0;

	if (!Gfx->Used)
		DisposalMethod = (Gfx->Packed & 0x1C) >> 2;
	if((size = iCurImage->io.getc(iCurImage->io.handle)) == IL_EOF)
		return IL_FALSE;

	if (size < 2 || 9 < size) {
		return IL_FALSE;
	}

	state.curr_size = size + 1;
	state.top_slot = 1 << state.curr_size;
	state.clear = 1 << size;
	state.ending = state.clear + 1;
	state.slot = state.newcodes = state.ending + 1;
	state.navail_bytes = state.nbits_left = 0;
	oc = fc = 0;

	while ((c = get_next_code(&state)) != state.ending 
	&&     Read < Height
	&& state.isValid()) 
	{
		if (c == state.clear)
		{
			state.curr_size = size + 1;
			state.slot = state.newcodes;
			state.top_slot = 1 << state.curr_size;
			while ((c = get_next_code(&state)) == state.clear);
			if (c == state.ending)
				break;
			if (c >= state.slot)
				c = 0;
			oc = fc = c;

			if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == c && (Gfx->Packed & 0x1) != 0)
				x++;
			else if (x < Width) {
				Data[dataOffset+x] = c;
            ++x;
         }

			if (x >= Width)
			{
				//DataPtr += Stride;
				x = 0;
				Read += 1;
				++y;
            dataOffset = y * Stride +  OffX;
				if (y >= Height) {
				   return IL_FALSE;
				}
			}
		}
		else
		{
			code = c;
         //BG-2007-01-10: several fixes for incomplete GIFs
			if (code >= state.slot)
			{
				code = oc;
				if (!state.stackIndexLegal()) {
					return IL_FALSE;
				}
				state.push(fc);
			}

			if (code >= MAX_CODES)
				return IL_FALSE; 
			while (code >= state.newcodes)
			{
				if (!state.stackIndexLegal()) {
					return IL_FALSE;
				}
				state.push(state.getSuffix(code));
				code = state.getPrefix(code);
			}
            
			if (!state.stackIndexLegal()) {
				return IL_FALSE;
			}

			state.push((ILbyte)code);
			if (state.slot < state.top_slot)
			{
				fc = code;
				state.setSuffix(fc);
				state.setPrefix(oc);
				oc = c;
			}
			if (state.slot >= state.top_slot && state.curr_size < 12)
			{
				state.top_slot <<= 1;
				state.curr_size++;
			}
			while (state.getStackIndex() > 0)
			{
				state.pop();
				if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == state.getStack()
            &&  (Gfx->Packed & 0x1) != 0)
            {
					x++;
            } else if (x < Width) {
					Data[dataOffset+x] = state.getStack();
               x++;
            }

				if (x >= Width) // end of line
				{
					x = OffX % Width;
					Read += 1;
               y = (y+1) % Height;
					// Needs to start from Data, not Image->Data.
					dataOffset = y * Stride +  OffX;
				}
			}
		}
	}

	return state.isValid();
}
Пример #8
0
short decoder (int i_linewidth)
{
  short linewidth;
  FAST UTINY *sp, *bufptr;
  UTINY *buf;
  FAST short code, fc, oc, bufcnt;
  short c, size, ret;

  linewidth = (short)i_linewidth;

  /* Initialize for decoding a new image...
    */
  if ((size = gif_get_byte()) < 0)
    return(size);
  if (size < 2 || 9 < size)
    return(BAD_CODE_SIZE);
  init_exp((int)size);        /* changed param to int */

  dstack = (UTINY *)POV_MALLOC((MAX_CODES + 1)*sizeof(UTINY), "GIF dstack");
  suffix = (UTINY *)POV_MALLOC((MAX_CODES + 1)*sizeof(UTINY), "GIF suffix");
  prefix = (UWORD *)POV_MALLOC((MAX_CODES + 1)*sizeof(UWORD), "GIF prefix");

  /* Initialize in case they forgot to put in a clear code.
    * (This shouldn't happen, but we'll try and decode it anyway...)
    */
  oc = fc = 0;

  buf = decoderline;

  bad_code_count = 0;

  /* Set up the stack pointer and decode buffer pointer
    */
  sp = dstack;
  bufptr = buf;
  bufcnt = linewidth;

  /* This is the main loop.  For each code we get we pass through the
    * linked list of prefix codes, pushing the corresponding "character" for
    * each code onto the stack.  When the list reaches a single "character"
    * we push that on the stack too, and then start unstacking each
    * character for output in the correct order.  Special handling is
    * included for the clear code, and the whole thing ends when we get
    * an ending code.
    */
  while ((c = get_next_code()) != ending)
    {

    Do_Cooperate(0);

    /* If we had a file error, return without completing the decode
       */
    if (c < 0) 
      {
      cleanup_gif_decoder();
      return(0);
      }

    /* If the code is a clear code, reinitialize all necessary items.
       */
    if (c == clear_code)
      {
      curr_size = size + 1;
      slot = newcodes;
      top_slot = 1 << curr_size;

      /* Continue reading codes until we get a non-clear code
          * (Another unlikely, but possible case...)
          */
      while ((c = get_next_code()) == clear_code)
        ;

      /* If we get an ending code immediately after a clear code
          * (Yet another unlikely case), then break out of the loop.
          */
      if (c == ending)
        break;

      /* Finally, if the code is beyond the range of already set codes,
          * (This one had better NOT happen...  I have no idea what will
          * result from this, but I doubt it will look good...) then set it
          * to color zero.
          */
      if (c >= slot)
        c = 0;

      oc = fc = c;

      /* And let us not forget to put the char into the buffer... And
          * if, on the off chance, we were exactly one pixel from the end
          * of the line, we have to send the buffer to the out_line()
          * routine...
          */
      *bufptr++ = (UTINY) c;
      if (--bufcnt == 0)
        {
        Do_Cooperate(1);
        if ((ret = out_line(buf, linewidth)) < 0) 
          {
          cleanup_gif_decoder();
          return(ret);
          }

        bufptr = buf;
        bufcnt = linewidth;
        }
      }
    else
      {

      /* In this case, it's not a clear code or an ending code, so
          * it must be a code code...  So we can now decode the code into
          * a stack of character codes. (Clear as mud, right?)
          */
      code = c;

      /* Here we go again with one of those off chances...  If, on the
          * off chance, the code we got is beyond the range of those already
          * set up (Another thing which had better NOT happen...) we trick
          * the decoder into thinking it actually got the last code read.
          * (Hmmn... I'm not sure why this works...  But it does...)
          */
      if (code >= slot)
        {
        if (code > slot)
          ++bad_code_count;
        code = oc;
        *sp++ = (UTINY) fc;
        }

      /* Here we scan back along the linked list of prefixes, pushing
          * helpless characters (ie. suffixes) onto the stack as we do so.
          */
      while (code >= newcodes)
        {
        *sp++ = suffix[code];
        code = prefix[code];
        }

      /* Push the last character on the stack, and set up the new
          * prefix and suffix, and if the required slot number is greater
          * than that allowed by the current bit size, increase the bit
          * size.  (NOTE - If we are all full, we *don't* save the new
          * suffix and prefix...  I'm not certain if this is correct...
          * it might be more proper to overwrite the last code...
          */
      *sp++ = (UTINY) code;
      if (slot < top_slot)
        {
        fc = code;
        suffix[slot] = (UTINY) fc;
        prefix[slot++] = oc;
        oc = c;
        }
      if (slot >= top_slot)
        if (curr_size < 12)
          {
          top_slot <<= 1;
          ++curr_size;
          }

      /* Now that we've pushed the decoded string (in reverse order)
          * onto the stack, lets pop it off and put it into our decode
          * buffer...  And when the decode buffer is full, write another
          * line...
          */
      while (sp > dstack)
        {
        *bufptr++ = *(--sp);
        if (--bufcnt == 0)
          {
          Do_Cooperate(1);
          if ((ret = out_line(buf, linewidth)) < 0) 
            {
            cleanup_gif_decoder();
            return(ret);
            }
          bufptr = buf;
          bufcnt = linewidth;
          }
        }
      }
    }
  ret = 0;
  if (bufcnt != linewidth)
    ret = out_line(buf, (linewidth - bufcnt));

  cleanup_gif_decoder();
  return(ret);
}
Пример #9
0
short LZWReader::Decoder()
	{
	BYTE *sp, *bufptr;
	BYTE *buf;
	DWORD bufcnt;
	int c, oc, fc, code, size;

	/* Initialize for decoding a new image...
	 */
	/*if ((size = get_byte()) < 0)
		return (size);
	if (size < 2 || 9 < size)
		return (BAD_CODE_SIZE);*/
	size = 8;
	init_exp(size);

	/* Initialize in case they forgot to put in a clear code.
	 * (This shouldn't happen, but we'll try and decode it anyway...)
	 */
	oc = fc = 0;

	/* Allocate space for the decode buffer
	 */
	buf = NextLine();

	/* Set up the stack pointer and decode buffer pointer
	 */
	sp = stack;
	bufptr = buf;
	bufcnt = m_width;

	/* This is the main loop.  For each code we get we pass through the
	 * linked list of prefix codes, pushing the corresponding "character" for
	 * each code onto the stack.  When the list reaches a single "character"
	 * we push that on the stack too, and then start unstacking each
	 * character for output in the correct order.  Special handling is
	 * included for the clear code, and the whole thing ends when we get
	 * an ending code.
	 */
	while ((c = get_next_code()) != ending)
		{

		/* If we had a file error, return without completing the decode
		 */
		if (c < 0)
			{
			break;
			//return (0);
			}

		/* If the code is a clear code, reinitialize all necessary items.
		 */
		if (c == clear)
			{
			curr_size = size + 1;
			slot = newcodes;
			top_slot = 1 << curr_size;

			/* Continue reading codes until we get a non-clear code
			 * (Another unlikely, but possible case...)
			 */
			while ((c = get_next_code()) == clear)
				;

			/* If we get an ending code immediately after a clear code
			 * (Yet another unlikely case), then break out of the loop.
			 */
			if (c == ending)
				break;

			/* Finally, if the code is beyond the range of already set codes,
			 * (This one had better NOT happen...  I have no idea what will
			 * result from this, but I doubt it will look good...) then set it
			 * to color zero.
			 */
			if (c >= slot)
				c = 0;

			oc = fc = c;

			/* And let us not forget to put the char into the buffer... And
			 * if, on the off chance, we were exactly one pixel from the end
			 * of the line, we have to send the buffer to the out_line()
			 * routine...
			 */
			*bufptr++ = (BYTE) c;
			if (--bufcnt == 0)
				{
				buf = NextLine();
				bufptr = buf;
				bufcnt = m_width;
				}
			}
		else
			{

			/* In this case, it's not a clear code or an ending code, so
			 * it must be a code code...  So we can now decode the code into
			 * a stack of character codes. (Clear as mud, right?)
			 */
			code = c;

			/* Here we go again with one of those off chances...  If, on the
			 * off chance, the code we got is beyond the range of those already
			 * set up (Another thing which had better NOT happen...) we trick
			 * the decoder into thinking it actually got the last code read.
			 * (Hmmn... I'm not sure why this works...  But it does...)
			 */
			if (code >= slot)
				{
				if (code > slot)
					++bad_code_count;
				code = oc;
				*sp++ = (BYTE) fc;
				}

			/* Here we scan back along the linked list of prefixes, pushing
			 * helpless characters (ie. suffixes) onto the stack as we do so.
			 */
			while (code >= newcodes)
				{
				*sp++ = suffix[code];
				code = prefix[code];
				}

			/* Push the last character on the stack, and set up the new
			 * prefix and suffix, and if the required slot number is greater
			 * than that allowed by the current bit size, increase the bit
			 * size.  (NOTE - If we are all full, we *don't* save the new
			 * suffix and prefix...  I'm not certain if this is correct...
			 * it might be more proper to overwrite the last code...
			 */
			*sp++ = (BYTE) code;
			if (slot < top_slot)
				{
				fc = code;
				suffix[slot] = (BYTE) fc;	// = code;
				prefix[slot++] = (WCHAR) oc;
				oc = c;
				}
			if (slot >= top_slot)
				if (curr_size < 12)
					{
					top_slot <<= 1;
					++curr_size;
					}

				/* Now that we've pushed the decoded string (in reverse order)
				 * onto the stack, lets pop it off and put it into our decode
				 * buffer...  And when the decode buffer is full, write another
				 * line...
				 */
			while (sp > stack)
				{
				*bufptr++ = *(--sp);
				if (--bufcnt == 0)
					{
					buf = NextLine();
					bufptr = buf;
					bufcnt = m_width;
					}
				}
			}
		}

	// BUG - is all this necessary?  Is it correct?
	int toofar = m_readahead - m_cfilebuffer; // bytes we already read that we shouldn't have
	toofar--;  // m_readahead == the byte we just read, so we actually used up one more than the math shows
	LARGE_INTEGER li;
	li.QuadPart = -toofar;
	m_pstm->Seek(li, STREAM_SEEK_CUR, NULL);

	return (0);
	}