Commit message: * tools/tiffcrop.c: fix out-of-bound read of up to 3 bytes in
readContigTilesIntoBuffer(). Reported as MSVR 35092 by Axel Souchet
& Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team.
CVE: CVE-2016-9539
CWE: CWE-125
Vulnerability description: tools/tiffcrop.c in libtiff 4.0.6 has an out-of-bounds read in readContigTilesIntoBuffer(). Reported as MSVR 35092.

Project: libtiff

combineSeparateSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
                              uint32 rows, uint16 spp, uint16 bps, 
 	                      FILE *dumpfile, int format, int level)
  {
  int    ready_bits = 0 /*, bytes_per_sample = 0 */;
  uint32 src_rowsize, dst_rowsize; 
  uint32 bit_offset, src_offset;
  uint32 row, col, src_byte = 0, src_bit = 0;
  uint16 maskbits = 0, matchbits = 0;
  uint16 buff1 = 0, buff2 = 0;
  uint8  bytebuff = 0;
  tsample_t s;
  unsigned char *src = in[0];
  unsigned char *dst = out;
  char           action[8];

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("combineSeparateSamples16bits","Invalid input or output buffer");
    return (1);
    }

  /* bytes_per_sample = (bps + 7) / 8; */ 
  src_rowsize = ((bps * cols) + 7) / 8;
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
  maskbits = (uint16)-1 >> (16 - bps);

  for (row = 0; row < rows; row++)
    {
    ready_bits = 0;
    buff1 = buff2 = 0;
    dst = out + (row * dst_rowsize);
    src_offset = row * src_rowsize;
    for (col = 0; col < cols; col++)
      {
      /* Compute src byte(s) and bits within byte(s) */
      bit_offset = col * bps;
      src_byte = bit_offset / 8;
      src_bit  = bit_offset % 8;

      matchbits = maskbits << (16 - src_bit - bps); 
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
        {
	src = in[s] + src_offset + src_byte;
        if (little_endian)
          buff1 = (src[0] << 8) | src[1];
        else
          buff1 = (src[1] << 8) | src[0];

	buff1 = (buff1 & matchbits) << (src_bit);

	/* If we have a full buffer's worth, write it out */
	if (ready_bits >= 8)
	  {
	    bytebuff = (buff2 >> 8);
	    *dst++ = bytebuff;
	    ready_bits -= 8;
	    /* shift in new bits */
	    buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
	    strcpy (action, "Flush");
	  }
	else
	  { /* add another bps bits to the buffer */
	    bytebuff = 0;
	    buff2 = (buff2 | (buff1 >> ready_bits));
	    strcpy (action, "Update");
	  }
	ready_bits += bps;

	if ((dumpfile != NULL) && (level == 3))
	  {
	  dump_info (dumpfile, format, "",
		       "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		       row + 1, col + 1, s, src_byte, src_bit, dst - out);

	  dump_short (dumpfile, format, "Match bits", matchbits);
	  dump_data  (dumpfile, format, "Src   bits", src, 2);
	  dump_short (dumpfile, format, "Buff1 bits", buff1);
	  dump_short (dumpfile, format, "Buff2 bits", buff2);
	  dump_byte  (dumpfile, format, "Write byte", bytebuff);
	  dump_info  (dumpfile, format, "","Ready bits:  %d, %s", ready_bits, action); 
	  }
	}
      }

    /* catch any trailing bits at the end of the line */
    if (ready_bits > 0)
      {
      bytebuff = (buff2 >> 8);
      *dst++ = bytebuff;
      if ((dumpfile != NULL) && (level == 3))
	{
	dump_info (dumpfile, format, "",
		       "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		       row + 1, col + 1, src_byte, src_bit, dst - out);
	dump_byte (dumpfile, format, "Final bits", bytebuff);
	}
      }

    if ((dumpfile != NULL) && (level == 2))
      {
      dump_info (dumpfile, format, "combineSeparateSamples16bits","Output data");
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
      }
    }

  return (0);
  } /* end combineSeparateSamples16bits */

Project: libtiff

combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
                              uint32 rows, uint16 spp, uint16 bps, 
	                      FILE *dumpfile, int format, int level)
  {
  int    ready_bits = 0 /*, bytes_per_sample = 0 */;
  uint32 src_rowsize, dst_rowsize; 
  uint32 bit_offset, src_offset;
  uint32 row, col, src_byte = 0, src_bit = 0;
  uint32 maskbits = 0, matchbits = 0;
  uint32 buff1 = 0, buff2 = 0;
  uint8  bytebuff1 = 0, bytebuff2 = 0;
  tsample_t s;
  unsigned char *src = in[0];
  unsigned char *dst = out;
  char           action[8];

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("combineSeparateSamples24bits","Invalid input or output buffer");
    return (1);
    }

  /* bytes_per_sample = (bps + 7) / 8; */ 
  src_rowsize = ((bps * cols) + 7) / 8;
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
  maskbits =  (uint32)-1 >> ( 32 - bps);

  for (row = 0; row < rows; row++)
    {
    ready_bits = 0;
    buff1 = buff2 = 0;
    dst = out + (row * dst_rowsize);
    src_offset = row * src_rowsize;
    for (col = 0; col < cols; col++)
      {
      /* Compute src byte(s) and bits within byte(s) */
      bit_offset = col * bps;
      src_byte = bit_offset / 8;
      src_bit  = bit_offset % 8;

      matchbits = maskbits << (32 - src_bit - bps); 
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
        {
	src = in[s] + src_offset + src_byte;
        if (little_endian)
	  buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
        else
	  buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
	buff1 = (buff1 & matchbits) << (src_bit);

	/* If we have a full buffer's worth, write it out */
	if (ready_bits >= 16)
	  {
	    bytebuff1 = (buff2 >> 24);
	    *dst++ = bytebuff1;
	    bytebuff2 = (buff2 >> 16);
	    *dst++ = bytebuff2;
	    ready_bits -= 16;

	    /* shift in new bits */
	    buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
	    strcpy (action, "Flush");
	  }
	else
	  { /* add another bps bits to the buffer */
	    bytebuff1 = bytebuff2 = 0;
	    buff2 = (buff2 | (buff1 >> ready_bits));
	    strcpy (action, "Update");
	  }
	ready_bits += bps;

	if ((dumpfile != NULL) && (level == 3))
	  {
	  dump_info (dumpfile, format, "",
		       "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		       row + 1, col + 1, s, src_byte, src_bit, dst - out);
	  dump_long (dumpfile, format, "Match bits ", matchbits);
	  dump_data (dumpfile, format, "Src   bits ", src, 4);
	  dump_long (dumpfile, format, "Buff1 bits ", buff1);
	  dump_long (dumpfile, format, "Buff2 bits ", buff2);
	  dump_byte (dumpfile, format, "Write bits1", bytebuff1);
	  dump_byte (dumpfile, format, "Write bits2", bytebuff2);
	  dump_info (dumpfile, format, "","Ready bits:   %d, %s", ready_bits, action); 
	  }
	}
      }

    /* catch any trailing bits at the end of the line */
    while (ready_bits > 0)
      {
	bytebuff1 = (buff2 >> 24);
	*dst++ = bytebuff1;

	buff2 = (buff2 << 8);
	bytebuff2 = bytebuff1;
	ready_bits -= 8;
      }
 
    if ((dumpfile != NULL) && (level == 3))
      {
      dump_info (dumpfile, format, "",
		   "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		   row + 1, col + 1, src_byte, src_bit, dst - out);

      dump_long (dumpfile, format, "Match bits ", matchbits);
      dump_data (dumpfile, format, "Src   bits ", src, 4);
      dump_long (dumpfile, format, "Buff1 bits ", buff1);
      dump_long (dumpfile, format, "Buff2 bits ", buff2);
      dump_byte (dumpfile, format, "Write bits1", bytebuff1);
      dump_byte (dumpfile, format, "Write bits2", bytebuff2);
      dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
      }

    if ((dumpfile != NULL) && (level == 2))
      {
      dump_info (dumpfile, format, "combineSeparateSamples24bits","Output data");
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
      }
    }
  
  return (0);
  } /* end combineSeparateSamples24bits */

Project: libtiff

combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
                              uint32 rows, uint16 spp, uint16 bps, 
	                      FILE *dumpfile, int format, int level)
  {
  int    ready_bits = 0 /*, bytes_per_sample = 0, shift_width = 0 */;
  uint32 src_rowsize, dst_rowsize, bit_offset, src_offset;
  uint32 src_byte = 0, src_bit = 0;
  uint32 row, col;
  uint32 longbuff1 = 0, longbuff2 = 0;
  uint64 maskbits = 0, matchbits = 0;
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
  tsample_t s;
  unsigned char *src = in[0];
  unsigned char *dst = out;
  char           action[8];

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("combineSeparateSamples32bits","Invalid input or output buffer");
    return (1);
    }

  /* bytes_per_sample = (bps + 7) / 8; */ 
  src_rowsize = ((bps * cols) + 7) / 8;
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
  maskbits =  (uint64)-1 >> ( 64 - bps);
  /* shift_width = ((bps + 7) / 8) + 1; */ 

  for (row = 0; row < rows; row++)
    {
    ready_bits = 0;
    buff1 = buff2 = 0;
    dst = out + (row * dst_rowsize);
    src_offset = row * src_rowsize;
    for (col = 0; col < cols; col++)
      {
      /* Compute src byte(s) and bits within byte(s) */
      bit_offset = col * bps;
      src_byte = bit_offset / 8;
      src_bit  = bit_offset % 8;

      matchbits = maskbits << (64 - src_bit - bps); 
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
	{
	src = in[s] + src_offset + src_byte;
	if (little_endian)
	  {
	  longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
          longbuff2 = longbuff1;
	  }
	else
	  {
	  longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
          longbuff2 = longbuff1;
	  }
	buff3 = ((uint64)longbuff1 << 32) | longbuff2;
	buff1 = (buff3 & matchbits) << (src_bit);

	/* If we have a full buffer's worth, write it out */
	if (ready_bits >= 32)
	  {
	  bytebuff1 = (buff2 >> 56);
	  *dst++ = bytebuff1;
	  bytebuff2 = (buff2 >> 48);
	  *dst++ = bytebuff2;
	  bytebuff3 = (buff2 >> 40);
	  *dst++ = bytebuff3;
	  bytebuff4 = (buff2 >> 32);
	  *dst++ = bytebuff4;
	  ready_bits -= 32;
                    
	  /* shift in new bits */
	  buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
	  strcpy (action, "Flush");
	  }
	else
	  { /* add another bps bits to the buffer */
	  bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
	  buff2 = (buff2 | (buff1 >> ready_bits));
	  strcpy (action, "Update");
	  }
	ready_bits += bps;

	if ((dumpfile != NULL) && (level == 3))
	  { 
	  dump_info (dumpfile, format, "",
		     "Row %3d, Col %3d, Sample %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		     row + 1, col + 1, s, src_byte, src_bit, dst - out);
	  dump_wide (dumpfile, format, "Match bits ", matchbits);
	  dump_data (dumpfile, format, "Src   bits ", src, 8);
	  dump_wide (dumpfile, format, "Buff1 bits ", buff1);
	  dump_wide (dumpfile, format, "Buff2 bits ", buff2);
	  dump_info (dumpfile, format, "", "Ready bits:   %d, %s", ready_bits, action); 
	  }
	}
      }
    while (ready_bits > 0)
      {
      bytebuff1 = (buff2 >> 56);
      *dst++ = bytebuff1;
      buff2 = (buff2 << 8);
      ready_bits -= 8;
      }

    if ((dumpfile != NULL) && (level == 3))
      {
      dump_info (dumpfile, format, "",
	         "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		 row + 1, col + 1, src_byte, src_bit, dst - out);

      dump_long (dumpfile, format, "Match bits ", matchbits);
      dump_data (dumpfile, format, "Src   bits ", src, 4);
      dump_long (dumpfile, format, "Buff1 bits ", buff1);
      dump_long (dumpfile, format, "Buff2 bits ", buff2);
      dump_byte (dumpfile, format, "Write bits1", bytebuff1);
      dump_byte (dumpfile, format, "Write bits2", bytebuff2);
      dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
      }

    if ((dumpfile != NULL) && (level == 2))
      {
      dump_info (dumpfile, format, "combineSeparateSamples32bits","Output data");
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out);
      }
    }
  
  return (0);
  } /* end combineSeparateSamples32bits */

Project: libtiff

combineSeparateSamples8bits (uint8 *in[], uint8 *out, uint32 cols,
                            uint32 rows, uint16 spp, uint16 bps, 
 	                    FILE *dumpfile, int format, int level)
  {
  int    ready_bits = 0;
  /* int    bytes_per_sample = 0; */
  uint32 src_rowsize, dst_rowsize, src_offset; 
  uint32 bit_offset;
  uint32 row, col, src_byte = 0, src_bit = 0;
  uint8  maskbits = 0, matchbits = 0;
  uint8  buff1 = 0, buff2 = 0;
  tsample_t s;
  unsigned char *src = in[0];
  unsigned char *dst = out;
  char           action[32];

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("combineSeparateSamples8bits","Invalid input or output buffer");
    return (1);
    }

  /* bytes_per_sample = (bps + 7) / 8; */ 
  src_rowsize = ((bps * cols) + 7) / 8;
  dst_rowsize = ((bps * cols * spp) + 7) / 8;
  maskbits =  (uint8)-1 >> ( 8 - bps);

  for (row = 0; row < rows; row++)
    {
    ready_bits = 0;
    buff1 = buff2 = 0;
    dst = out + (row * dst_rowsize);
    src_offset = row * src_rowsize;
    for (col = 0; col < cols; col++)
      {
      /* Compute src byte(s) and bits within byte(s) */
      bit_offset = col * bps;
      src_byte = bit_offset / 8;
      src_bit  = bit_offset % 8;

      matchbits = maskbits << (8 - src_bit - bps); 
      /* load up next sample from each plane */
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
        {
	src = in[s] + src_offset + src_byte;
        buff1 = ((*src) & matchbits) << (src_bit);

        /* If we have a full buffer's worth, write it out */
        if (ready_bits >= 8)
          {
          *dst++ = buff2;
          buff2 = buff1;
          ready_bits -= 8;
          strcpy (action, "Flush");
          }
        else
          {
          buff2 = (buff2 | (buff1 >> ready_bits));
          strcpy (action, "Update");
          }
        ready_bits += bps;
 
        if ((dumpfile != NULL) && (level == 3))
          {
          dump_info (dumpfile, format, "",
                   "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		   row + 1, col + 1, s, src_byte, src_bit, dst - out);
          dump_byte (dumpfile, format, "Match bits", matchbits);
          dump_byte (dumpfile, format, "Src   bits", *src);
          dump_byte (dumpfile, format, "Buff1 bits", buff1);
          dump_byte (dumpfile, format, "Buff2 bits", buff2);
          dump_info (dumpfile, format, "","%s", action); 
	  }
        }
      }

    if (ready_bits > 0)
      {
      buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
      *dst++ = buff1;
      if ((dumpfile != NULL) && (level == 3))
        {
        dump_info (dumpfile, format, "",
	         "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
	         row + 1, col + 1, src_byte, src_bit, dst - out);
                 dump_byte (dumpfile, format, "Final bits", buff1);
        }
      }

    if ((dumpfile != NULL) && (level >= 2))
      {
      dump_info (dumpfile, format, "combineSeparateSamples8bits","Output data");
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
      }
    }

  return (0);
  } /* end combineSeparateSamples8bits */

Project: libtiff

combineSeparateSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
                             uint32 cols, uint32 rows, uint16 spp, uint16 bps,
                             FILE *dumpfile, int format, int level)
  {
  int i, bytes_per_sample;
  uint32 row, col, col_offset, src_rowsize, dst_rowsize, row_offset;
  unsigned char *src;
  unsigned char *dst;
  tsample_t s;

  src = srcbuffs[0];
  dst = out;
  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("combineSeparateSamplesBytes","Invalid buffer address");
    return (1);
    }

  bytes_per_sample = (bps + 7) / 8; 

  src_rowsize = ((bps * cols) + 7) / 8;
  dst_rowsize = ((bps * spp * cols) + 7) / 8;
  for (row = 0; row < rows; row++)
    {
    if ((dumpfile != NULL) && (level == 2))
      {
      for (s = 0; s < spp; s++)
        {
        dump_info (dumpfile, format, "combineSeparateSamplesBytes","Input data, Sample %d", s);
        dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
        }
      }
    dst = out + (row * dst_rowsize);
    row_offset = row * src_rowsize;
    for (col = 0; col < cols; col++)
      {
      col_offset = row_offset + (col * (bps / 8)); 
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
        {
        src = srcbuffs[s] + col_offset; 
        for (i = 0; i < bytes_per_sample; i++)
          *(dst + i) = *(src + i);
        src += bytes_per_sample;
        dst += bytes_per_sample;
        }   
      }

    if ((dumpfile != NULL) && (level == 2))
      {
      dump_info (dumpfile, format, "combineSeparateSamplesBytes","Output data, combined samples");
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
      }
    }

  return (0);
  } /* end combineSeparateSamplesBytes */

Project: libtiff

combineSeparateTileSamples16bits (uint8 *in[], uint8 *out, uint32 cols,
                                  uint32 rows, uint32 imagewidth, 
                                  uint32 tw, uint16 spp, uint16 bps, 
 	                          FILE *dumpfile, int format, int level)
  {
  int    ready_bits = 0;
  uint32 src_rowsize, dst_rowsize; 
  uint32 bit_offset, src_offset;
  uint32 row, col, src_byte = 0, src_bit = 0;
  uint16 maskbits = 0, matchbits = 0;
  uint16 buff1 = 0, buff2 = 0;
  uint8  bytebuff = 0;
  tsample_t s;
  unsigned char *src = in[0];
  unsigned char *dst = out;
  char           action[8];

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("combineSeparateTileSamples16bits","Invalid input or output buffer");
    return (1);
    }

  src_rowsize = ((bps * tw) + 7) / 8;
  dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
  maskbits = (uint16)-1 >> (16 - bps);

  for (row = 0; row < rows; row++)
    {
    ready_bits = 0;
    buff1 = buff2 = 0;
    dst = out + (row * dst_rowsize);
    src_offset = row * src_rowsize;
    for (col = 0; col < cols; col++)
      {
      /* Compute src byte(s) and bits within byte(s) */
      bit_offset = col * bps;
      src_byte = bit_offset / 8;
      src_bit  = bit_offset % 8;

      matchbits = maskbits << (16 - src_bit - bps); 
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
        {
	src = in[s] + src_offset + src_byte;
        if (little_endian)
          buff1 = (src[0] << 8) | src[1];
        else
          buff1 = (src[1] << 8) | src[0];
	buff1 = (buff1 & matchbits) << (src_bit);

	/* If we have a full buffer's worth, write it out */
	if (ready_bits >= 8)
	  {
	    bytebuff = (buff2 >> 8);
	    *dst++ = bytebuff;
	    ready_bits -= 8;
	    /* shift in new bits */
	    buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
	    strcpy (action, "Flush");
	  }
	else
	  { /* add another bps bits to the buffer */
	    bytebuff = 0;
	    buff2 = (buff2 | (buff1 >> ready_bits));
	    strcpy (action, "Update");
	  }
	ready_bits += bps;

	if ((dumpfile != NULL) && (level == 3))
	  {
	  dump_info (dumpfile, format, "",
		       "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		       row + 1, col + 1, s, src_byte, src_bit, dst - out);

	  dump_short (dumpfile, format, "Match bits", matchbits);
	  dump_data  (dumpfile, format, "Src   bits", src, 2);
	  dump_short (dumpfile, format, "Buff1 bits", buff1);
	  dump_short (dumpfile, format, "Buff2 bits", buff2);
	  dump_byte  (dumpfile, format, "Write byte", bytebuff);
	  dump_info  (dumpfile, format, "","Ready bits:  %d, %s", ready_bits, action); 
	  }
	}
      }

    /* catch any trailing bits at the end of the line */
    if (ready_bits > 0)
      {
      bytebuff = (buff2 >> 8);
      *dst++ = bytebuff;
      if ((dumpfile != NULL) && (level == 3))
	{
	dump_info (dumpfile, format, "",
		       "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		       row + 1, col + 1, src_byte, src_bit, dst - out);
	dump_byte (dumpfile, format, "Final bits", bytebuff);
	}
      }

    if ((dumpfile != NULL) && (level == 2))
      {
      dump_info (dumpfile, format, "combineSeparateTileSamples16bits","Output data");
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
      }
    }

  return (0);
  } /* end combineSeparateTileSamples16bits */

Project: libtiff

combineSeparateTileSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
                                  uint32 rows, uint32 imagewidth, 
                                  uint32 tw, uint16 spp, uint16 bps, 
 	                          FILE *dumpfile, int format, int level)
  {
  int    ready_bits = 0;
  uint32 src_rowsize, dst_rowsize; 
  uint32 bit_offset, src_offset;
  uint32 row, col, src_byte = 0, src_bit = 0;
  uint32 maskbits = 0, matchbits = 0;
  uint32 buff1 = 0, buff2 = 0;
  uint8  bytebuff1 = 0, bytebuff2 = 0;
  tsample_t s;
  unsigned char *src = in[0];
  unsigned char *dst = out;
  char           action[8];

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("combineSeparateTileSamples24bits","Invalid input or output buffer");
    return (1);
    }

  src_rowsize = ((bps * tw) + 7) / 8;
  dst_rowsize = ((imagewidth * bps * spp) + 7) / 8;
  maskbits =  (uint32)-1 >> ( 32 - bps);

  for (row = 0; row < rows; row++)
    {
    ready_bits = 0;
    buff1 = buff2 = 0;
    dst = out + (row * dst_rowsize);
    src_offset = row * src_rowsize;
    for (col = 0; col < cols; col++)
      {
      /* Compute src byte(s) and bits within byte(s) */
      bit_offset = col * bps;
      src_byte = bit_offset / 8;
      src_bit  = bit_offset % 8;

      matchbits = maskbits << (32 - src_bit - bps); 
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
        {
	src = in[s] + src_offset + src_byte;
        if (little_endian)
	  buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
        else
	  buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
	buff1 = (buff1 & matchbits) << (src_bit);

	/* If we have a full buffer's worth, write it out */
	if (ready_bits >= 16)
	  {
	    bytebuff1 = (buff2 >> 24);
	    *dst++ = bytebuff1;
	    bytebuff2 = (buff2 >> 16);
	    *dst++ = bytebuff2;
	    ready_bits -= 16;

	    /* shift in new bits */
	    buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
	    strcpy (action, "Flush");
	  }
	else
	  { /* add another bps bits to the buffer */
	    bytebuff1 = bytebuff2 = 0;
	    buff2 = (buff2 | (buff1 >> ready_bits));
	    strcpy (action, "Update");
	  }
	ready_bits += bps;

	if ((dumpfile != NULL) && (level == 3))
	  {
	  dump_info (dumpfile, format, "",
		       "Row %3d, Col %3d, Samples %d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		       row + 1, col + 1, s, src_byte, src_bit, dst - out);
	  dump_long (dumpfile, format, "Match bits ", matchbits);
	  dump_data (dumpfile, format, "Src   bits ", src, 4);
	  dump_long (dumpfile, format, "Buff1 bits ", buff1);
	  dump_long (dumpfile, format, "Buff2 bits ", buff2);
	  dump_byte (dumpfile, format, "Write bits1", bytebuff1);
	  dump_byte (dumpfile, format, "Write bits2", bytebuff2);
	  dump_info (dumpfile, format, "","Ready bits:   %d, %s", ready_bits, action); 
	  }
	}
      }

    /* catch any trailing bits at the end of the line */
    while (ready_bits > 0)
      {
	bytebuff1 = (buff2 >> 24);
	*dst++ = bytebuff1;

	buff2 = (buff2 << 8);
	bytebuff2 = bytebuff1;
	ready_bits -= 8;
      }
 
    if ((dumpfile != NULL) && (level == 3))
      {
      dump_info (dumpfile, format, "",
		   "Row %3d, Col %3d, Src byte offset %3d  bit offset %2d  Dst offset %3d",
		   row + 1, col + 1, src_byte, src_bit, dst - out);

      dump_long (dumpfile, format, "Match bits ", matchbits);
      dump_data (dumpfile, format, "Src   bits ", src, 4);
      dump_long (dumpfile, format, "Buff1 bits ", buff1);
      dump_long (dumpfile, format, "Buff2 bits ", buff2);
      dump_byte (dumpfile, format, "Write bits1", bytebuff1);
      dump_byte (dumpfile, format, "Write bits2", bytebuff2);
      dump_info (dumpfile, format, "", "Ready bits:  %2d", ready_bits); 
      }

    if ((dumpfile != NULL) && (level == 2))
      {
      dump_info (dumpfile, format, "combineSeparateTileSamples24bits","Output data");
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
      }
    }
  
  return (0);
  } /* end combineSeparateTileSamples24bits */

Project: libtiff

combineSeparateTileSamplesBytes (unsigned char *srcbuffs[], unsigned char *out,
                                 uint32 cols, uint32 rows, uint32 imagewidth,
                                 uint32 tw, uint16 spp, uint16 bps,
                                 FILE *dumpfile, int format, int level)
  {
  int i, bytes_per_sample;
  uint32 row, col, col_offset, src_rowsize, dst_rowsize, src_offset;
  unsigned char *src;
  unsigned char *dst;
  tsample_t s;

  src = srcbuffs[0];
  dst = out;
  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("combineSeparateTileSamplesBytes","Invalid buffer address");
    return (1);
    }

  bytes_per_sample = (bps + 7) / 8; 
  src_rowsize = ((bps * tw) + 7) / 8;
  dst_rowsize = imagewidth * bytes_per_sample * spp;
  for (row = 0; row < rows; row++)
    {
    if ((dumpfile != NULL) && (level == 2))
      {
      for (s = 0; s < spp; s++)
        {
        dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Input data, Sample %d", s);
        dump_buffer(dumpfile, format, 1, cols, row, srcbuffs[s] + (row * src_rowsize));
        }
      }
    dst = out + (row * dst_rowsize);
    src_offset = row * src_rowsize;
#ifdef DEVELMODE
    TIFFError("","Tile row %4d, Src offset %6d   Dst offset %6d", 
              row, src_offset, dst - out);
#endif
    for (col = 0; col < cols; col++)
      {
      col_offset = src_offset + (col * (bps / 8)); 
      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
        {
        src = srcbuffs[s] + col_offset; 
        for (i = 0; i < bytes_per_sample; i++)
          *(dst + i) = *(src + i);
        dst += bytes_per_sample;
        }   
      }

    if ((dumpfile != NULL) && (level == 2))
      {
      dump_info (dumpfile, format, "combineSeparateTileSamplesBytes","Output data, combined samples");
      dump_buffer(dumpfile, format, 1, dst_rowsize, row, out + (row * dst_rowsize));
      }
    }

  return (0);
  } /* end combineSeparateTileSamplesBytes */

Project: libtiff

computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
                         struct offset *off)
  {
  double scale;
  float xres, yres;
  /* Values for these offsets are in pixels from start of image, not bytes,
   * and are indexed from zero to width - 1 or length - 1 */
  uint32 tmargin, bmargin, lmargin, rmargin;
  uint32 startx, endx;   /* offsets of first and last columns to extract */
  uint32 starty, endy;   /* offsets of first and last row to extract */
  uint32 width, length, crop_width, crop_length; 
  uint32 i, max_width, max_length, zwidth, zlength, buffsize;
  uint32 x1, x2, y1, y2;

  if (image->res_unit != RESUNIT_INCH && image->res_unit != RESUNIT_CENTIMETER)
    {
    xres = 1.0;
    yres = 1.0;
    }
  else
    {
    if (((image->xres == 0) || (image->yres == 0)) && 
         (crop->res_unit != RESUNIT_NONE) &&
	((crop->crop_mode & CROP_REGIONS) || (crop->crop_mode & CROP_MARGINS) ||
 	 (crop->crop_mode & CROP_LENGTH)  || (crop->crop_mode & CROP_WIDTH)))
      {
      TIFFError("computeInputPixelOffsets", "Cannot compute margins or fixed size sections without image resolution");
      TIFFError("computeInputPixelOffsets", "Specify units in pixels and try again");
      return (-1);
      }
    xres = image->xres;
    yres = image->yres;
    }

  /* Translate user units to image units */
  scale = 1.0;
  switch (crop->res_unit) {
    case RESUNIT_CENTIMETER:
         if (image->res_unit == RESUNIT_INCH)
	   scale = 1.0/2.54;
	 break;
    case RESUNIT_INCH:
	 if (image->res_unit == RESUNIT_CENTIMETER)
	     scale = 2.54;
	 break;
    case RESUNIT_NONE: /* Dimensions in pixels */
    default:
    break;
    }

  if (crop->crop_mode & CROP_REGIONS)
    {
    max_width = max_length = 0;
    for (i = 0; i < crop->regions; i++)
      {
      if ((crop->res_unit == RESUNIT_INCH) || (crop->res_unit == RESUNIT_CENTIMETER))
        {
	x1 = (uint32) (crop->corners[i].X1 * scale * xres);
	x2 = (uint32) (crop->corners[i].X2 * scale * xres);
	y1 = (uint32) (crop->corners[i].Y1 * scale * yres);
	y2 = (uint32) (crop->corners[i].Y2 * scale * yres);
        }
      else
        {
	x1 = (uint32) (crop->corners[i].X1);
	x2 = (uint32) (crop->corners[i].X2);
	y1 = (uint32) (crop->corners[i].Y1);
	y2 = (uint32) (crop->corners[i].Y2);       
	}
      if (x1 < 1)
        crop->regionlist[i].x1 = 0;
      else
        crop->regionlist[i].x1 = (uint32) (x1 - 1);

      if (x2 > image->width - 1)
        crop->regionlist[i].x2 = image->width - 1;
      else
        crop->regionlist[i].x2 = (uint32) (x2 - 1);
      zwidth  = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 

      if (y1 < 1)
        crop->regionlist[i].y1 = 0;
      else
        crop->regionlist[i].y1 = (uint32) (y1 - 1);

      if (y2 > image->length - 1)
        crop->regionlist[i].y2 = image->length - 1;
      else
        crop->regionlist[i].y2 = (uint32) (y2 - 1);

      zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; 

      if (zwidth > max_width)
        max_width = zwidth;
      if (zlength > max_length)
        max_length = zlength;

      buffsize = (uint32)
          (((zwidth * image->bps * image->spp + 7 ) / 8) * (zlength + 1));

      crop->regionlist[i].buffsize = buffsize;
      crop->bufftotal += buffsize;
      if (crop->img_mode == COMPOSITE_IMAGES)
        {
        switch (crop->edge_ref)
          {
          case EDGE_LEFT:
          case EDGE_RIGHT:
               crop->combined_length = zlength;
               crop->combined_width += zwidth;
               break;
          case EDGE_BOTTOM:
          case EDGE_TOP:  /* width from left, length from top */
          default:
               crop->combined_width = zwidth;
               crop->combined_length += zlength;
	       break;
          }
	}
      }
    return (0);
    }
  
  /* Convert crop margins into offsets into image
   * Margins are expressed as pixel rows and columns, not bytes
   */
  if (crop->crop_mode & CROP_MARGINS)
    {
    if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
      { /* User has specified pixels as reference unit */
      tmargin = (uint32)(crop->margins[0]);
      lmargin = (uint32)(crop->margins[1]);
      bmargin = (uint32)(crop->margins[2]);
      rmargin = (uint32)(crop->margins[3]);
      }
    else
      { /* inches or centimeters specified */
      tmargin = (uint32)(crop->margins[0] * scale * yres);
      lmargin = (uint32)(crop->margins[1] * scale * xres);
      bmargin = (uint32)(crop->margins[2] * scale * yres);
      rmargin = (uint32)(crop->margins[3] * scale * xres);
      }

    if ((lmargin + rmargin) > image->width)
      {
      TIFFError("computeInputPixelOffsets", "Combined left and right margins exceed image width");
      lmargin = (uint32) 0;
      rmargin = (uint32) 0;
      return (-1);
      }
    if ((tmargin + bmargin) > image->length)
      {
      TIFFError("computeInputPixelOffsets", "Combined top and bottom margins exceed image length"); 
      tmargin = (uint32) 0; 
      bmargin = (uint32) 0;
      return (-1);
      }
    }
  else
    { /* no margins requested */
    tmargin = (uint32) 0;
    lmargin = (uint32) 0;
    bmargin = (uint32) 0;
    rmargin = (uint32) 0;
    }

  /* Width, height, and margins are expressed as pixel offsets into image */
  if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER)
    {
    if (crop->crop_mode & CROP_WIDTH)
      width = (uint32)crop->width;
    else
      width = image->width - lmargin - rmargin;

    if (crop->crop_mode & CROP_LENGTH)
      length  = (uint32)crop->length;
    else
      length = image->length - tmargin - bmargin;
    }
  else
    {
    if (crop->crop_mode & CROP_WIDTH)
      width = (uint32)(crop->width * scale * image->xres);
    else
      width = image->width - lmargin - rmargin;

    if (crop->crop_mode & CROP_LENGTH)
      length  = (uint32)(crop->length * scale * image->yres);
    else
      length = image->length - tmargin - bmargin;
    }

  off->tmargin = tmargin;
  off->bmargin = bmargin;
  off->lmargin = lmargin;
  off->rmargin = rmargin;

  /* Calculate regions defined by margins, width, and length. 
   * Coordinates expressed as 0 to imagewidth - 1, imagelength - 1,
   * since they are used to compute offsets into buffers */
  switch (crop->edge_ref) {
    case EDGE_BOTTOM:
         startx = lmargin;
         if ((startx + width) >= (image->width - rmargin))
           endx = image->width - rmargin - 1;
         else
           endx = startx + width - 1;

         endy = image->length - bmargin - 1;
         if ((endy - length) <= tmargin)
           starty = tmargin;
         else
           starty = endy - length + 1;
         break;
    case EDGE_RIGHT:
         endx = image->width - rmargin - 1;
         if ((endx - width) <= lmargin)
           startx = lmargin;
         else
           startx = endx - width + 1;

         starty = tmargin;
         if ((starty + length) >= (image->length - bmargin))
           endy = image->length - bmargin - 1;
         else
           endy = starty + length - 1;
         break;
    case EDGE_TOP:  /* width from left, length from top */
    case EDGE_LEFT:
    default:
         startx = lmargin;
         if ((startx + width) >= (image->width - rmargin))
           endx = image->width - rmargin - 1;
         else
           endx = startx + width - 1;

         starty = tmargin;
         if ((starty + length) >= (image->length - bmargin))
           endy = image->length - bmargin - 1;
         else
           endy = starty + length - 1;
         break;
    }
  off->startx = startx;
  off->starty = starty;
  off->endx   = endx;
  off->endy   = endy;

  crop_width  = endx - startx + 1;
  crop_length = endy - starty + 1;

  if (crop_width <= 0)
    {
    TIFFError("computeInputPixelOffsets", 
               "Invalid left/right margins and /or image crop width requested");
    return (-1);
    }
  if (crop_width > image->width)
    crop_width = image->width;

  if (crop_length <= 0)
    {
    TIFFError("computeInputPixelOffsets", 
              "Invalid top/bottom margins and /or image crop length requested");
    return (-1);
    }
  if (crop_length > image->length)
    crop_length = image->length;

  off->crop_width = crop_width;
  off->crop_length = crop_length;

  return (0);
  } /* end computeInputPixelOffsets */

Project: libtiff

computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image,
                           struct pagedef *page, struct pageseg *sections,
                           struct dump_opts* dump)
  {
  double scale;
  double pwidth, plength;          /* Output page width and length in user units*/
  uint32 iwidth, ilength;          /* Input image width and length in pixels*/
  uint32 owidth, olength;          /* Output image width and length in pixels*/
  uint32 orows, ocols;             /* rows and cols for output */
  uint32 hmargin, vmargin;         /* Horizontal and vertical margins */
  uint32 x1, x2, y1, y2, line_bytes;
  /* unsigned int orientation; */
  uint32 i, j, k;
 
  scale = 1.0;
  if (page->res_unit == RESUNIT_NONE)
    page->res_unit = image->res_unit;

  switch (image->res_unit) {
    case RESUNIT_CENTIMETER:
         if (page->res_unit == RESUNIT_INCH)
	   scale = 1.0/2.54;
	 break;
    case RESUNIT_INCH:
	 if (page->res_unit == RESUNIT_CENTIMETER)
	     scale = 2.54;
	 break;
    case RESUNIT_NONE: /* Dimensions in pixels */
    default:
    break;
    }

  /* get width, height, resolutions of input image selection */
  if (crop->combined_width > 0)
    iwidth = crop->combined_width;
  else
    iwidth = image->width;
  if (crop->combined_length > 0)
    ilength = crop->combined_length;
  else
    ilength = image->length;

  if (page->hres <= 1.0)
    page->hres = image->xres;
  if (page->vres <= 1.0)
    page->vres = image->yres;

  if ((page->hres < 1.0) || (page->vres < 1.0))
    {
    TIFFError("computeOutputPixelOffsets",
    "Invalid horizontal or vertical resolution specified or read from input image");
    return (1);
    }

  /* If no page sizes are being specified, we just use the input image size to
   * calculate maximum margins that can be taken from image.
   */
  if (page->width <= 0)
    pwidth = iwidth;
  else
    pwidth = page->width;

  if (page->length <= 0)
    plength = ilength;
  else
    plength = page->length;

  if (dump->debug)
    {
    TIFFError("", "Page size: %s, Vres: %3.2f, Hres: %3.2f, "
                   "Hmargin: %3.2f, Vmargin: %3.2f",
	     page->name, page->vres, page->hres,
             page->hmargin, page->vmargin);
    TIFFError("", "Res_unit: %d, Scale: %3.2f, Page width: %3.2f, length: %3.2f", 
           page->res_unit, scale, pwidth, plength);
    }

  /* compute margins at specified unit and resolution */
  if (page->mode & PAGE_MODE_MARGINS)
    {
    if (page->res_unit == RESUNIT_INCH || page->res_unit == RESUNIT_CENTIMETER)
      { /* inches or centimeters specified */
      hmargin = (uint32)(page->hmargin * scale * page->hres * ((image->bps + 7)/ 8));
      vmargin = (uint32)(page->vmargin * scale * page->vres * ((image->bps + 7)/ 8));
      }
    else
      { /* Otherwise user has specified pixels as reference unit */
      hmargin = (uint32)(page->hmargin * scale * ((image->bps + 7)/ 8));
      vmargin = (uint32)(page->vmargin * scale * ((image->bps + 7)/ 8));
      }

    if ((hmargin * 2.0) > (pwidth * page->hres))
      {
      TIFFError("computeOutputPixelOffsets", 
                "Combined left and right margins exceed page width");
      hmargin = (uint32) 0;
      return (-1);
      }
    if ((vmargin * 2.0) > (plength * page->vres))
      {
      TIFFError("computeOutputPixelOffsets", 
                "Combined top and bottom margins exceed page length"); 
      vmargin = (uint32) 0; 
      return (-1);
      }
    }
  else
    {
    hmargin = 0;
    vmargin = 0;
    }

  if (page->mode & PAGE_MODE_ROWSCOLS )
    {
    /* Maybe someday but not for now */
    if (page->mode & PAGE_MODE_MARGINS)
      TIFFError("computeOutputPixelOffsets", 
      "Output margins cannot be specified with rows and columns"); 

    owidth  = TIFFhowmany(iwidth, page->cols);
    olength = TIFFhowmany(ilength, page->rows);
    }
  else
    {
    if (page->mode & PAGE_MODE_PAPERSIZE )
      {
      owidth  = (uint32)((pwidth * page->hres) - (hmargin * 2));
      olength = (uint32)((plength * page->vres) - (vmargin * 2));
      }
    else
      {
      owidth = (uint32)(iwidth - (hmargin * 2 * page->hres));
      olength = (uint32)(ilength - (vmargin * 2 * page->vres));
      }
    }

  if (owidth > iwidth)
    owidth = iwidth;
  if (olength > ilength)
    olength = ilength;

  /* Compute the number of pages required for Portrait or Landscape */
  switch (page->orient)
    {
    case ORIENTATION_NONE:
    case ORIENTATION_PORTRAIT:
         ocols = TIFFhowmany(iwidth, owidth);
         orows = TIFFhowmany(ilength, olength);
         /* orientation = ORIENTATION_PORTRAIT; */
         break;

    case ORIENTATION_LANDSCAPE:
         ocols = TIFFhowmany(iwidth, olength);
         orows = TIFFhowmany(ilength, owidth);
         x1 = olength;
         olength = owidth;
         owidth = x1;
         /* orientation = ORIENTATION_LANDSCAPE; */
         break;

    case ORIENTATION_AUTO:
    default:
         x1 = TIFFhowmany(iwidth, owidth);
         x2 = TIFFhowmany(ilength, olength); 
         y1 = TIFFhowmany(iwidth, olength);
         y2 = TIFFhowmany(ilength, owidth); 

         if ( (x1 * x2) < (y1 * y2))
           { /* Portrait */
           ocols = x1;
           orows = x2;
           /* orientation = ORIENTATION_PORTRAIT; */
	   }
         else
           { /* Landscape */
           ocols = y1;
           orows = y2;
           x1 = olength;
           olength = owidth;
           owidth = x1;
           /* orientation = ORIENTATION_LANDSCAPE; */
           }
    }

  if (ocols < 1)
    ocols = 1;
  if (orows < 1)
    orows = 1;

  /* If user did not specify rows and cols, set them from calcuation */
  if (page->rows < 1)
    page->rows = orows;
  if (page->cols < 1)
    page->cols = ocols;

  line_bytes = TIFFhowmany8(owidth * image->bps) * image->spp;

  if ((page->rows * page->cols) > MAX_SECTIONS)
   {
   TIFFError("computeOutputPixelOffsets",
	     "Rows and Columns exceed maximum sections\nIncrease resolution or reduce sections");
   return (-1);
   }

  /* build the list of offsets for each output section */
  for (k = 0, i = 0 && k <= MAX_SECTIONS; i < orows; i++)
    {
    y1 = (uint32)(olength * i);
    y2 = (uint32)(olength * (i +  1) - 1);
    if (y2 >= ilength)
      y2 = ilength - 1;
    for (j = 0; j < ocols; j++, k++)
      {
      x1 = (uint32)(owidth * j); 
      x2 = (uint32)(owidth * (j + 1) - 1);
      if (x2 >= iwidth)
        x2 = iwidth - 1;
      sections[k].x1 = x1;
      sections[k].x2 = x2;
      sections[k].y1 = y1;
      sections[k].y2 = y2;
      sections[k].buffsize = line_bytes * olength;
      sections[k].position = k + 1;
      sections[k].total = orows * ocols;
      } 
    } 
  return (0);
  } /* end computeOutputPixelOffsets */

Project: libtiff

static int  correct_orientation(struct image_data *image, unsigned char **work_buff_ptr)
  {
  uint16 mirror, rotation;
  unsigned char *work_buff;

  work_buff = *work_buff_ptr;
  if ((image == NULL) || (work_buff == NULL))
    {
    TIFFError ("correct_orientatin", "Invalid image or buffer pointer");
    return (-1);
    }

  if ((image->adjustments & MIRROR_HORIZ) || (image->adjustments & MIRROR_VERT))
    {
    mirror = (uint16)(image->adjustments & MIRROR_BOTH);
    if (mirrorImage(image->spp, image->bps, mirror, 
        image->width, image->length, work_buff))
      {
      TIFFError ("correct_orientation", "Unable to mirror image");
      return (-1);
      }
    }

  if (image->adjustments & ROTATE_ANY)
    {
    if (image->adjustments & ROTATECW_90)
      rotation = (uint16) 90;
    else
    if (image->adjustments & ROTATECW_180)
      rotation = (uint16) 180;
    else
    if (image->adjustments & ROTATECW_270)
      rotation = (uint16) 270;
    else
      {
      TIFFError ("correct_orientation", "Invalid rotation value: %d", 
                  image->adjustments & ROTATE_ANY);
      return (-1);
      }
 
    if (rotateImage(rotation, image, &image->width, &image->length, work_buff_ptr))
      {
      TIFFError ("correct_orientation", "Unable to rotate image");
      return (-1);
      }
    image->orientation = ORIENTATION_TOPLEFT;
    }

  return (0);
  } /* end correct_orientation */

Project: libtiff

cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
{
	switch (type) {
	case TIFF_SHORT:
		if (count == 1) {
			uint16 shortv;
			CopyField(tag, shortv);
		} else if (count == 2) {
			uint16 shortv1, shortv2;
			CopyField2(tag, shortv1, shortv2);
		} else if (count == 4) {
			uint16 *tr, *tg, *tb, *ta;
			CopyField4(tag, tr, tg, tb, ta);
		} else if (count == (uint16) -1) {
			uint16 shortv1;
			uint16* shortav;
			CopyField2(tag, shortv1, shortav);
		}
		break;
	case TIFF_LONG:
		{ uint32 longv;
		  CopyField(tag, longv);
		}
		break;
	case TIFF_RATIONAL:
		if (count == 1) {
			float floatv;
			CopyField(tag, floatv);
		} else if (count == (uint16) -1) {
			float* floatav;
			CopyField(tag, floatav);
		}
		break;
	case TIFF_ASCII:
		{ char* stringv;
		  CopyField(tag, stringv);
		}
		break;
	case TIFF_DOUBLE:
		if (count == 1) {
			double doublev;
			CopyField(tag, doublev);
		} else if (count == (uint16) -1) {
			double* doubleav;
			CopyField(tag, doubleav);
		}
		break;
          default:
                TIFFError(TIFFFileName(in),
                          "Data type %d is not supported, tag %d skipped",
                          tag, type);
	}
}

Project: libtiff

createCroppedImage(struct image_data *image, struct crop_mask *crop, 
                   unsigned char **read_buff_ptr, unsigned char **crop_buff_ptr)
  {
  tsize_t   cropsize;
  unsigned  char *read_buff = NULL;
  unsigned  char *crop_buff = NULL;
  unsigned  char *new_buff  = NULL;
  static    tsize_t  prev_cropsize = 0;

  read_buff = *read_buff_ptr;

  /* process full image, no crop buffer needed */
  crop_buff = read_buff;
  *crop_buff_ptr = read_buff;
  crop->combined_width = image->width;
  crop->combined_length = image->length;

  cropsize = crop->bufftotal;
  crop_buff = *crop_buff_ptr;
  if (!crop_buff)
    {
    crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
    *crop_buff_ptr = crop_buff;
    _TIFFmemset(crop_buff, 0, cropsize);
    prev_cropsize = cropsize;
    }
  else
    {
    if (prev_cropsize < cropsize)
      {
      new_buff = _TIFFrealloc(crop_buff, cropsize);
      if (!new_buff)
        {
	free (crop_buff);
        crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
        }
      else
        crop_buff = new_buff;
      _TIFFmemset(crop_buff, 0, cropsize);
      }
    }

  if (!crop_buff)
    {
    TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
    return (-1);
    }
  *crop_buff_ptr = crop_buff;

  if (crop->crop_mode & CROP_INVERT)
    {
    switch (crop->photometric)
      {
      /* Just change the interpretation */
      case PHOTOMETRIC_MINISWHITE:
      case PHOTOMETRIC_MINISBLACK:
	   image->photometric = crop->photometric;
	   break;
      case INVERT_DATA_ONLY:
      case INVERT_DATA_AND_TAG:
           if (invertImage(image->photometric, image->spp, image->bps, 
                           crop->combined_width, crop->combined_length, crop_buff))
             {
             TIFFError("createCroppedImage", 
                       "Failed to invert colorspace for image or cropped selection");
             return (-1);
             }
           if (crop->photometric == INVERT_DATA_AND_TAG)
             {
             switch (image->photometric)
               {
               case PHOTOMETRIC_MINISWHITE:
 	            image->photometric = PHOTOMETRIC_MINISBLACK;
	            break;
               case PHOTOMETRIC_MINISBLACK:
 	            image->photometric = PHOTOMETRIC_MINISWHITE;
	            break;
               default:
	            break;
	       }
	     }
           break;
      default: break;
      }
    }

  if (crop->crop_mode & CROP_MIRROR)
    {
    if (mirrorImage(image->spp, image->bps, crop->mirror, 
                    crop->combined_width, crop->combined_length, crop_buff))
      {
      TIFFError("createCroppedImage", "Failed to mirror image or cropped selection %s", 
	       (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
      return (-1);
      }
    }

  if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
    {
    if (rotateImage(crop->rotation, image, &crop->combined_width, 
                    &crop->combined_length, crop_buff_ptr))
      {
      TIFFError("createCroppedImage", 
                "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
      return (-1);
      }
    }

  if (crop_buff == read_buff) /* we used the read buffer for the crop buffer */
    *read_buff_ptr = NULL;    /* so we don't try to free it later */

  return (0);
  } /* end createCroppedImage */

Project: libtiff

createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
  {
  unsigned  char *sect_buff = NULL;
  unsigned  char *new_buff  = NULL;
  static    uint32  prev_sectsize = 0;
  
  sect_buff = *sect_buff_ptr;

  if (!sect_buff)
    {
    sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
    *sect_buff_ptr = sect_buff;
    _TIFFmemset(sect_buff, 0, sectsize);
    }
  else
    {
    if (prev_sectsize < sectsize)
      {
      new_buff = _TIFFrealloc(sect_buff, sectsize);
      if (!new_buff)
        {
	free (sect_buff);
        sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
        }
      else
        sect_buff = new_buff;

      _TIFFmemset(sect_buff, 0, sectsize);
      }
    }

  if (!sect_buff)
    {
    TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
    return (-1);
    }
  prev_sectsize = sectsize;
  *sect_buff_ptr = sect_buff;

  return (0);
  }  /* end createImageSection */

Project: libtiff

static int dump_byte (FILE *dumpfile, int format, char *dump_tag, unsigned char data)
  {
  int j, k;
  char  dump_array[10];
  unsigned char bitset;

  if (dumpfile == NULL)
    {
    TIFFError ("", "Invalid FILE pointer for dump file");
    return (1);
    }

  if (format == DUMP_TEXT)
    {
    fprintf (dumpfile," %s  ", dump_tag);
    for (j = 0, k = 7; j < 8; j++, k--)
      {
      bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
      }
    dump_array[8] = '\0';
    fprintf (dumpfile," %s\n", dump_array);
    }
  else
    {
    if ((fwrite (&data, 1, 1, dumpfile)) != 1)
      {
      TIFFError ("", "Unable to write binary data to dump file");
      return (1);
      }
    }

  return (0);
  }

Project: libtiff

static int dump_data (FILE *dumpfile, int format, char *dump_tag, unsigned char *data, uint32 count)
  {
  int j, k;
  uint32 i;
  char  dump_array[10];
  unsigned char bitset;

  if (dumpfile == NULL)
    {
    TIFFError ("", "Invalid FILE pointer for dump file");
    return (1);
    }

  if (format == DUMP_TEXT)
    {
    fprintf (dumpfile," %s  ", dump_tag);
    for (i = 0; i < count; i++)
      {
      for (j = 0, k = 7; j < 8; j++, k--)
        {
	bitset = (*(data + i)) & (((unsigned char)1 << k)) ? 1 : 0;
        sprintf(&dump_array[j], (bitset) ? "1" : "0");
        }
      dump_array[8] = '\0';
      fprintf (dumpfile," %s", dump_array);
      }
    fprintf (dumpfile,"\n");
    }
  else
    {
    if ((fwrite (data, 1, count, dumpfile)) != count)
      {
      TIFFError ("", "Unable to write binary data to dump file");
      return (1);
      }
    }

  return (0);
  }

Project: libtiff

static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...)
  {
  if (format == DUMP_TEXT)
    {
    va_list ap;
    va_start(ap, msg);
    fprintf(dumpfile, "%s ", prefix);
    vfprintf(dumpfile, msg, ap);
    fprintf(dumpfile, "\n");
    va_end(ap);
    }
  }

Project: libtiff

static int dump_long (FILE *dumpfile, int format, char *dump_tag, uint32 data)
  {
  int j, k;
  char  dump_array[40];
  unsigned char bitset;

  if (dumpfile == NULL)
    {
    TIFFError ("", "Invalid FILE pointer for dump file");
    return (1);
    }

  if (format == DUMP_TEXT)
    {
    fprintf (dumpfile," %s  ", dump_tag);
    for (j = 0, k = 31; k >= 0; j++, k--)
      {
      bitset = data & (((uint32)1 << k)) ? 1 : 0;
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
      if ((k % 8) == 0)
          sprintf(&dump_array[++j], " ");
      }
    dump_array[35] = '\0';
    fprintf (dumpfile," %s\n", dump_array);
    }
  else
    {
    if ((fwrite (&data, 4, 1, dumpfile)) != 4)
      {
      TIFFError ("", "Unable to write binary data to dump file");
      return (1);
      }
    }
  return (0);
  }

Project: libtiff

static int dump_short (FILE *dumpfile, int format, char *dump_tag, uint16 data)
  {
  int j, k;
  char  dump_array[20];
  unsigned char bitset;

  if (dumpfile == NULL)
    {
    TIFFError ("", "Invalid FILE pointer for dump file");
    return (1);
    }

  if (format == DUMP_TEXT)
    {
    fprintf (dumpfile," %s  ", dump_tag);
    for (j = 0, k = 15; k >= 0; j++, k--)
      {
      bitset = data & (((unsigned char)1 << k)) ? 1 : 0;
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
      if ((k % 8) == 0)
          sprintf(&dump_array[++j], " ");
      }
    dump_array[17] = '\0';
    fprintf (dumpfile," %s\n", dump_array);
    }
  else
    {
    if ((fwrite (&data, 2, 1, dumpfile)) != 2)
      {
      TIFFError ("", "Unable to write binary data to dump file");
      return (1);
      }
    }

  return (0);
  }

Project: libtiff

static int dump_wide (FILE *dumpfile, int format, char *dump_tag, uint64 data)
  {
  int j, k;
  char  dump_array[80];
  unsigned char bitset;

  if (dumpfile == NULL)
    {
    TIFFError ("", "Invalid FILE pointer for dump file");
    return (1);
    }

  if (format == DUMP_TEXT)
    {
    fprintf (dumpfile," %s  ", dump_tag);
    for (j = 0, k = 63; k >= 0; j++, k--)
      {
      bitset = data & (((uint64)1 << k)) ? 1 : 0;
      sprintf(&dump_array[j], (bitset) ? "1" : "0");
      if ((k % 8) == 0)
          sprintf(&dump_array[++j], " ");
      }
    dump_array[71] = '\0';
    fprintf (dumpfile," %s\n", dump_array);
    }
  else
    {
    if ((fwrite (&data, 8, 1, dumpfile)) != 8)
      {
      TIFFError ("", "Unable to write binary data to dump file");
      return (1);
      }
    }

  return (0);
  }

Project: libtiff

extractCompositeRegions(struct image_data *image,  struct crop_mask *crop, 
                        unsigned char *read_buff, unsigned char *crop_buff)
  {
  int       shift_width, bytes_per_sample, bytes_per_pixel;
  uint32    i, trailing_bits, prev_trailing_bits;
  uint32    row, first_row, last_row, first_col, last_col;
  uint32    src_rowsize, dst_rowsize, src_offset, dst_offset;
  uint32    crop_width, crop_length, img_width /*, img_length */;
  uint32    prev_length, prev_width, composite_width;
  uint16    bps, spp;
  uint8    *src, *dst;
  tsample_t count, sample = 0;   /* Update to extract one or more samples */

  img_width = image->width;
  /* img_length = image->length; */
  bps = image->bps;
  spp = image->spp;
  count = spp;

  bytes_per_sample = (bps + 7) / 8; 
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
  if ((bps % 8) == 0)
    shift_width = 0;
  else
    {
    if (bytes_per_pixel < (bytes_per_sample + 1))
      shift_width = bytes_per_pixel;
    else
      shift_width = bytes_per_sample + 1;
    }
  src = read_buff;
  dst = crop_buff;

  /* These are setup for adding additional sections */
  prev_width = prev_length = 0;
  prev_trailing_bits = trailing_bits = 0;
  composite_width = crop->combined_width;
  crop->combined_width = 0;
  crop->combined_length = 0;

  for (i = 0; i < crop->selections; i++)
    {
    /* rows, columns, width, length are expressed in pixels */
    first_row = crop->regionlist[i].y1;
    last_row  = crop->regionlist[i].y2;
    first_col = crop->regionlist[i].x1;
    last_col  = crop->regionlist[i].x2;

    crop_width = last_col - first_col + 1;
    crop_length = last_row - first_row + 1;

    /* These should not be needed for composite images */
    crop->regionlist[i].width = crop_width;
    crop->regionlist[i].length = crop_length;
    crop->regionlist[i].buffptr = crop_buff;

    src_rowsize = ((img_width * bps * spp) + 7) / 8;
    dst_rowsize = (((crop_width * bps * count) + 7) / 8);

    switch (crop->edge_ref)
      {
      default:
      case EDGE_TOP:
      case EDGE_BOTTOM:
	   if ((i > 0) && (crop_width != crop->regionlist[i - 1].width))
             {
	     TIFFError ("extractCompositeRegions", 
                          "Only equal width regions can be combined for -E top or bottom");
	     return (1);
             }

           crop->combined_width = crop_width;
           crop->combined_length += crop_length;

           for (row = first_row; row <= last_row; row++)
             {
	     src_offset = row * src_rowsize;
	     dst_offset = (row - first_row) * dst_rowsize;
             src = read_buff + src_offset;
             dst = crop_buff + dst_offset + (prev_length * dst_rowsize);
             switch (shift_width)
               {
               case 0: if (extractContigSamplesBytes (src, dst, img_width, sample,
                                                      spp, bps, count, first_col,
                                                      last_col + 1))
                         {
		         TIFFError("extractCompositeRegions",
                                   "Unable to extract row %d", row);
		         return (1);
		         }
		       break;
               case 1: if (bps == 1)
                         { 
                         if (extractContigSamplesShifted8bits (src, dst, img_width,
                                                               sample, spp, bps, count, 
                                                               first_col, last_col + 1,
                                                               prev_trailing_bits))
                           {
		           TIFFError("extractCompositeRegions",
                                     "Unable to extract row %d", row);
		           return (1);
		           }
		         break;
			 }
                       else
                         if (extractContigSamplesShifted16bits (src, dst, img_width,
                                                                sample, spp, bps, count, 
                                                                first_col, last_col + 1,
                                                                prev_trailing_bits))
                           {
		           TIFFError("extractCompositeRegions",
                                     "Unable to extract row %d", row);
		           return (1);
		           }
		        break;
               case 2:  if (extractContigSamplesShifted24bits (src, dst, img_width,
                                                               sample, spp, bps, count, 
                                                               first_col, last_col + 1,
                                                               prev_trailing_bits))
                          {
		          TIFFError("extractCompositeRegions",
                                    "Unable to extract row %d", row);
		          return (1);
		          }
		        break;
               case 3:
               case 4:
               case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
                                                               sample, spp, bps, count, 
                                                               first_col, last_col + 1,
                                                               prev_trailing_bits))
                          {
		          TIFFError("extractCompositeRegions",
                                    "Unable to extract row %d", row);
		          return (1);
		          }
		        break;
               default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
		        return (1);
	       }
             }
           prev_length += crop_length;
	   break;
      case EDGE_LEFT:  /* splice the pieces of each row together, side by side */
      case EDGE_RIGHT:
	   if ((i > 0) && (crop_length != crop->regionlist[i - 1].length))
             {
	     TIFFError ("extractCompositeRegions", 
                          "Only equal length regions can be combined for -E left or right");
	     return (1);
             }
           crop->combined_width += crop_width;
           crop->combined_length = crop_length;
           dst_rowsize = (((composite_width * bps * count) + 7) / 8);
           trailing_bits = (crop_width * bps * count) % 8;
           for (row = first_row; row <= last_row; row++)
             {
	     src_offset = row * src_rowsize;
	     dst_offset = (row - first_row) * dst_rowsize;
             src = read_buff + src_offset;
             dst = crop_buff + dst_offset + prev_width;

             switch (shift_width)
               {
               case 0: if (extractContigSamplesBytes (src, dst, img_width,
                                                      sample, spp, bps, count,
                                                      first_col, last_col + 1))
                         {
		         TIFFError("extractCompositeRegions",
                                   "Unable to extract row %d", row);
		         return (1);
		         }
		       break;
               case 1: if (bps == 1)
                         { 
                         if (extractContigSamplesShifted8bits (src, dst, img_width,
                                                               sample, spp, bps, count, 
                                                               first_col, last_col + 1,
                                                               prev_trailing_bits))
                           {
		           TIFFError("extractCompositeRegions",
                                     "Unable to extract row %d", row);
		           return (1);
		           }
		         break;
			 }
                       else
                         if (extractContigSamplesShifted16bits (src, dst, img_width,
                                                                sample, spp, bps, count, 
                                                                first_col, last_col + 1,
                                                                prev_trailing_bits))
                           {
		           TIFFError("extractCompositeRegions",
                                     "Unable to extract row %d", row);
		           return (1);
		           }
		        break;
              case 2:  if (extractContigSamplesShifted24bits (src, dst, img_width,
                                                               sample, spp, bps, count, 
                                                               first_col, last_col + 1,
                                                               prev_trailing_bits))
                          {
		          TIFFError("extractCompositeRegions",
                                    "Unable to extract row %d", row);
		          return (1);
		          }
		        break;
               case 3:
               case 4:
               case 5:  if (extractContigSamplesShifted32bits (src, dst, img_width,
                                                               sample, spp, bps, count, 
                                                               first_col, last_col + 1,
                                                               prev_trailing_bits))
                          {
		          TIFFError("extractCompositeRegions",
                                    "Unable to extract row %d", row);
		          return (1);
		          }
		        break;
               default: TIFFError("extractCompositeRegions", "Unsupported bit depth %d", bps);
		        return (1);
	       }
	     }
	   prev_width += (crop_width * bps * count) / 8;
           prev_trailing_bits += trailing_bits;
           if (prev_trailing_bits > 7)
	     prev_trailing_bits-= 8;
	   break;
      }
    }
  if (crop->combined_width != composite_width)
    TIFFError("combineSeparateRegions","Combined width does not match composite width");
      
  return (0);
  }  /* end extractCompositeRegions */

Project: libtiff

extractContigSamples16bits (uint8 *in, uint8 *out, uint32 cols, 
                            tsample_t sample, uint16 spp, uint16 bps, 
                            tsample_t count, uint32 start, uint32 end)
  {
  int    ready_bits = 0, sindex = 0;
  uint32 col, src_byte, src_bit, bit_offset;
  uint16 maskbits = 0, matchbits = 0;
  uint16 buff1 = 0, buff2 = 0;
  uint8  bytebuff = 0;
  uint8 *src = in;
  uint8 *dst = out;

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("extractContigSamples16bits","Invalid input or output buffer");
    return (1);
    }

  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamples16bits", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamples16bits", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }

  ready_bits = 0;
  maskbits = (uint16)-1 >> (16 - bps);

  for (col = start; col < end; col++)
    {    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = col * bps * spp;
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
      {
      if (sindex == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sindex * bps)) / 8;
        src_bit  = (bit_offset + (sindex * bps)) % 8;
        }

      src = in + src_byte;
      matchbits = maskbits << (16 - src_bit - bps); 

      if (little_endian)
        buff1 = (src[0] << 8) | src[1];
      else
        buff1 = (src[1] << 8) | src[0];

      buff1 = (buff1 & matchbits) << (src_bit);
      if (ready_bits < 8) /* add another bps bits to the buffer */
        { 
        bytebuff = 0;
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      else /* If we have a full buffer's worth, write it out */
        {
        bytebuff = (buff2 >> 8);
        *dst++ = bytebuff;
        ready_bits -= 8;
        /* shift in new bits */
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }

  /* catch any trailing bits at the end of the line */
  while (ready_bits > 0)
    {
    bytebuff = (buff2 >> 8);
    *dst++ = bytebuff;
    ready_bits -= 8;
    }
  
  return (0);
  } /* end extractContigSamples16bits */

Project: libtiff

extractContigSamples24bits (uint8 *in, uint8 *out, uint32 cols,
 	                    tsample_t sample, uint16 spp, uint16 bps, 
                            tsample_t count, uint32 start, uint32 end)
  {
  int    ready_bits = 0, sindex = 0;
  uint32 col, src_byte, src_bit, bit_offset;
  uint32 maskbits = 0, matchbits = 0;
  uint32 buff1 = 0, buff2 = 0;
  uint8  bytebuff1 = 0, bytebuff2 = 0;
  uint8 *src = in;
  uint8 *dst = out;

  if ((in == NULL) || (out == NULL))
    {
    TIFFError("extractContigSamples24bits","Invalid input or output buffer");
    return (1);
    }

  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamples24bits", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamples24bits", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }

  ready_bits = 0;
  maskbits =  (uint32)-1 >> ( 32 - bps);
  for (col = start; col < end; col++)
    {
    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = col * bps * spp;
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
      {
      if (sindex == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sindex * bps)) / 8;
        src_bit  = (bit_offset + (sindex * bps)) % 8;
        }

      src = in + src_byte;
      matchbits = maskbits << (32 - src_bit - bps); 
      if (little_endian)
	buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
      else
	buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
      buff1 = (buff1 & matchbits) << (src_bit);

      if (ready_bits < 16) /* add another bps bits to the buffer */
        {
        bytebuff1 = bytebuff2 = 0;
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      else /* If we have a full buffer's worth, write it out */
        {
        bytebuff1 = (buff2 >> 24);
        *dst++ = bytebuff1;
        bytebuff2 = (buff2 >> 16);
        *dst++ = bytebuff2;
        ready_bits -= 16;

        /* shift in new bits */
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }

  /* catch any trailing bits at the end of the line */
  while (ready_bits > 0)
    {
    bytebuff1 = (buff2 >> 24);
    *dst++ = bytebuff1;

    buff2 = (buff2 << 8);
    bytebuff2 = bytebuff1;
    ready_bits -= 8;
    } 
  
  return (0);
  } /* end extractContigSamples24bits */

Project: libtiff

extractContigSamples32bits (uint8 *in, uint8 *out, uint32 cols,
                            tsample_t sample, uint16 spp, uint16 bps, 
 			    tsample_t count, uint32 start, uint32 end)
  {
  int    ready_bits = 0, sindex = 0 /*, shift_width = 0 */;
  uint32 col, src_byte, src_bit, bit_offset;
  uint32 longbuff1 = 0, longbuff2 = 0;
  uint64 maskbits = 0, matchbits = 0;
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
  uint8 *src = in;
  uint8 *dst = out;

  if ((in == NULL) || (out == NULL))
    {
    TIFFError("extractContigSamples32bits","Invalid input or output buffer");
    return (1);
    }


  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamples32bits", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamples32bits", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }

  /* shift_width = ((bps + 7) / 8) + 1; */ 
  ready_bits = 0;
  maskbits =  (uint64)-1 >> ( 64 - bps);
  for (col = start; col < end; col++)
    {
    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = col * bps * spp;
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
      {
      if (sindex == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sindex * bps)) / 8;
        src_bit  = (bit_offset + (sindex * bps)) % 8;
        }

      src = in + src_byte;
      matchbits = maskbits << (64 - src_bit - bps); 
      if (little_endian)
        {
	longbuff1 = (src[0] << 24) | (src[1] << 16)  | (src[2] << 8) | src[3];
	longbuff2 = longbuff1;
        }
      else
        {
	longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
	longbuff2 = longbuff1;
	}

      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
      buff1 = (buff3 & matchbits) << (src_bit);

      /* If we have a full buffer's worth, write it out */
      if (ready_bits >= 32)
        {
        bytebuff1 = (buff2 >> 56);
        *dst++ = bytebuff1;
        bytebuff2 = (buff2 >> 48);
        *dst++ = bytebuff2;
        bytebuff3 = (buff2 >> 40);
        *dst++ = bytebuff3;
        bytebuff4 = (buff2 >> 32);
        *dst++ = bytebuff4;
        ready_bits -= 32;
                    
        /* shift in new bits */
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
        }
      else
        { /* add another bps bits to the buffer */
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }
  while (ready_bits > 0)
    {
    bytebuff1 = (buff2 >> 56);
    *dst++ = bytebuff1;
    buff2 = (buff2 << 8);
    ready_bits -= 8;
    }
  
  return (0);
  } /* end extractContigSamples32bits */

Project: libtiff

extractContigSamples8bits (uint8 *in, uint8 *out, uint32 cols,
                           tsample_t sample, uint16 spp, uint16 bps, 
                           tsample_t count, uint32 start, uint32 end)
  {
  int    ready_bits = 0, sindex = 0;
  uint32 col, src_byte, src_bit, bit_offset;
  uint8  maskbits = 0, matchbits = 0;
  uint8  buff1 = 0, buff2 = 0;
  uint8 *src = in;
  uint8 *dst = out;

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("extractContigSamples8bits","Invalid input or output buffer");
    return (1);
    }

  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamples8bits", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamples8bits", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }
  
  ready_bits = 0;
  maskbits =  (uint8)-1 >> ( 8 - bps);
  buff1 = buff2 = 0;
  for (col = start; col < end; col++)
    {    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = col * bps * spp;
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
      {
      if (sindex == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sindex * bps)) / 8;
        src_bit  = (bit_offset + (sindex * bps)) % 8;
        }

      src = in + src_byte;
      matchbits = maskbits << (8 - src_bit - bps); 
      buff1 = ((*src) & matchbits) << (src_bit);

      /* If we have a full buffer's worth, write it out */
      if (ready_bits >= 8)
        {
        *dst++ = buff2;
        buff2 = buff1;
        ready_bits -= 8;
        }
      else
        buff2 = (buff2 | (buff1 >> ready_bits));
      ready_bits += bps;
      }
    }

  while (ready_bits > 0)
    {
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
    *dst++ = buff1;
    ready_bits -= 8;
    }

  return (0);
  } /* end extractContigSamples8bits */

Project: libtiff

extractContigSamplesBytes (uint8 *in, uint8 *out, uint32 cols, 
                           tsample_t sample, uint16 spp, uint16 bps, 
                           tsample_t count, uint32 start, uint32 end)
  {
  int i, bytes_per_sample, sindex;
  uint32 col, dst_rowsize, bit_offset;
  uint32 src_byte /*, src_bit */;
  uint8 *src = in;
  uint8 *dst = out;

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("extractContigSamplesBytes","Invalid input or output buffer");
    return (1);
    }

  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamplesBytes", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamplesBytes", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }

  dst_rowsize = (bps * (end - start) * count) / 8;

  bytes_per_sample = (bps + 7) / 8; 
  /* Optimize case for copying all samples */
  if (count == spp)
    {
    src = in + (start * spp * bytes_per_sample);
    _TIFFmemcpy (dst, src, dst_rowsize);
    }
  else
    {
    for (col = start; col < end; col++)
      {
      for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
        {
        bit_offset = col * bps * spp;
        if (sindex == 0)
          {
          src_byte = bit_offset / 8;
          /* src_bit  = bit_offset % 8; */
          }
        else
          {
          src_byte = (bit_offset + (sindex * bps)) / 8;
          /* src_bit  = (bit_offset + (sindex * bps)) % 8; */
          }
        src = in + src_byte;
        for (i = 0; i < bytes_per_sample; i++)
            *dst++ = *src++;
        }
      }
    }

  return (0);
  } /* end extractContigSamplesBytes */

Project: libtiff

extractContigSamplesShifted16bits (uint8 *in, uint8 *out, uint32 cols, 
                                   tsample_t sample, uint16 spp, uint16 bps, 
  			           tsample_t count, uint32 start, uint32 end,
 	                           int shift)
  {
  int    ready_bits = 0, sindex = 0;
  uint32 col, src_byte, src_bit, bit_offset;
  uint16 maskbits = 0, matchbits = 0;
  uint16 buff1 = 0, buff2 = 0;
  uint8  bytebuff = 0;
  uint8 *src = in;
  uint8 *dst = out;
  
  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("extractContigSamplesShifted16bits","Invalid input or output buffer");
    return (1);
    }

  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamplesShifted16bits", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamplesShifted16bits", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }

  ready_bits = shift;
  maskbits = (uint16)-1 >> (16 - bps);
  for (col = start; col < end; col++)
    {    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = col * bps * spp;
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
      {
      if (sindex == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sindex * bps)) / 8;
        src_bit  = (bit_offset + (sindex * bps)) % 8;
        }

      src = in + src_byte;
      matchbits = maskbits << (16 - src_bit - bps); 
      if (little_endian)
        buff1 = (src[0] << 8) | src[1];
      else
        buff1 = (src[1] << 8) | src[0];

      if ((col == start) && (sindex == sample))
        buff2 = buff1 & ((uint16)-1) << (8 - shift);

      buff1 = (buff1 & matchbits) << (src_bit);

      if (ready_bits < 8) /* add another bps bits to the buffer */
        buff2 = buff2 | (buff1 >> ready_bits);
      else  /* If we have a full buffer's worth, write it out */
        {
        bytebuff = (buff2 >> 8);
        *dst++ = bytebuff;
        ready_bits -= 8;
        /* shift in new bits */
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
        }

      ready_bits += bps;
      }
    }

  /* catch any trailing bits at the end of the line */
  while (ready_bits > 0)
    {
    bytebuff = (buff2 >> 8);
    *dst++ = bytebuff;
    ready_bits -= 8;
    }
  
  return (0);
  } /* end extractContigSamplesShifted16bits */

Project: libtiff

extractContigSamplesShifted24bits (uint8 *in, uint8 *out, uint32 cols,
 	                           tsample_t sample, uint16 spp, uint16 bps, 
                                   tsample_t count, uint32 start, uint32 end,
	                           int shift)
  {
  int    ready_bits = 0, sindex = 0;
  uint32 col, src_byte, src_bit, bit_offset;
  uint32 maskbits = 0, matchbits = 0;
  uint32 buff1 = 0, buff2 = 0;
  uint8  bytebuff1 = 0, bytebuff2 = 0;
  uint8 *src = in;
  uint8 *dst = out;

  if ((in == NULL) || (out == NULL))
    {
    TIFFError("extractContigSamplesShifted24bits","Invalid input or output buffer");
    return (1);
    }

  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamplesShifted24bits", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamplesShifted24bits", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }

  ready_bits = shift;
  maskbits =  (uint32)-1 >> ( 32 - bps);
  for (col = start; col < end; col++)
    {
    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = col * bps * spp;
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
      {
      if (sindex == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sindex * bps)) / 8;
        src_bit  = (bit_offset + (sindex * bps)) % 8;
        }

      src = in + src_byte;
      matchbits = maskbits << (32 - src_bit - bps); 
      if (little_endian)
	buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
      else
	buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];

      if ((col == start) && (sindex == sample))
        buff2 = buff1 & ((uint32)-1) << (16 - shift);

      buff1 = (buff1 & matchbits) << (src_bit);

      if (ready_bits < 16)  /* add another bps bits to the buffer */
        {
        bytebuff1 = bytebuff2 = 0;
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      else /* If we have a full buffer's worth, write it out */
        {
        bytebuff1 = (buff2 >> 24);
        *dst++ = bytebuff1;
        bytebuff2 = (buff2 >> 16);
        *dst++ = bytebuff2;
        ready_bits -= 16;

        /* shift in new bits */
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }

  /* catch any trailing bits at the end of the line */
  while (ready_bits > 0)
    {
    bytebuff1 = (buff2 >> 24);
    *dst++ = bytebuff1;

    buff2 = (buff2 << 8);
    bytebuff2 = bytebuff1;
    ready_bits -= 8;
    }
   
  return (0);
  } /* end extractContigSamplesShifted24bits */

Project: libtiff

extractContigSamplesShifted32bits (uint8 *in, uint8 *out, uint32 cols,
                                   tsample_t sample, uint16 spp, uint16 bps, 
 			           tsample_t count, uint32 start, uint32 end,
	                           int shift)
  {
  int    ready_bits = 0, sindex = 0 /*, shift_width = 0 */;
  uint32 col, src_byte, src_bit, bit_offset;
  uint32 longbuff1 = 0, longbuff2 = 0;
  uint64 maskbits = 0, matchbits = 0;
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
  uint8 *src = in;
  uint8 *dst = out;

  if ((in == NULL) || (out == NULL))
    {
    TIFFError("extractContigSamplesShifted32bits","Invalid input or output buffer");
    return (1);
    }


  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamplesShifted32bits", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamplesShifted32bits", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }

  /* shift_width = ((bps + 7) / 8) + 1; */ 
  ready_bits = shift;
  maskbits =  (uint64)-1 >> ( 64 - bps);
  for (col = start; col < end; col++)
    {
    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = col * bps * spp;
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
      {
      if (sindex == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sindex * bps)) / 8;
        src_bit  = (bit_offset + (sindex * bps)) % 8;
        }

      src = in + src_byte;
      matchbits = maskbits << (64 - src_bit - bps); 
      if (little_endian)
        {
	longbuff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
	longbuff2 = longbuff1;
        }
      else
        {
	longbuff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
	longbuff2 = longbuff1;
	}

      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
      if ((col == start) && (sindex == sample))
        buff2 = buff3 & ((uint64)-1) << (32 - shift);

      buff1 = (buff3 & matchbits) << (src_bit);

      if (ready_bits < 32)
        { /* add another bps bits to the buffer */
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      else  /* If we have a full buffer's worth, write it out */
        {
        bytebuff1 = (buff2 >> 56);
        *dst++ = bytebuff1;
        bytebuff2 = (buff2 >> 48);
        *dst++ = bytebuff2;
        bytebuff3 = (buff2 >> 40);
        *dst++ = bytebuff3;
        bytebuff4 = (buff2 >> 32);
        *dst++ = bytebuff4;
        ready_bits -= 32;
                    
        /* shift in new bits */
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }
  while (ready_bits > 0)
    {
    bytebuff1 = (buff2 >> 56);
    *dst++ = bytebuff1;
    buff2 = (buff2 << 8);
    ready_bits -= 8;
    }
  
  return (0);
  } /* end extractContigSamplesShifted32bits */

Project: libtiff

extractContigSamplesShifted8bits (uint8 *in, uint8 *out, uint32 cols,
                                  tsample_t sample, uint16 spp, uint16 bps, 
			          tsample_t count, uint32 start, uint32 end,
 	                          int shift)
  {
  int    ready_bits = 0, sindex = 0;
  uint32 col, src_byte, src_bit, bit_offset;
  uint8  maskbits = 0, matchbits = 0;
  uint8  buff1 = 0, buff2 = 0;
  uint8 *src = in;
  uint8 *dst = out;

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("extractContigSamplesShifted8bits","Invalid input or output buffer");
    return (1);
    }

  if ((start > end) || (start > cols))
    {
    TIFFError ("extractContigSamplesShifted8bits", 
               "Invalid start column value %d ignored", start);
    start = 0;
    }
  if ((end == 0) || (end > cols))
    {
    TIFFError ("extractContigSamplesShifted8bits", 
               "Invalid end column value %d ignored", end);
    end = cols;
    }

  ready_bits = shift;
  maskbits =  (uint8)-1 >> ( 8 - bps);
  buff1 = buff2 = 0;
  for (col = start; col < end; col++)
    {    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = col * bps * spp;
    for (sindex = sample; (sindex < spp) && (sindex < (sample + count)); sindex++)
      {
      if (sindex == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sindex * bps)) / 8;
        src_bit  = (bit_offset + (sindex * bps)) % 8;
        }

      src = in + src_byte;
      matchbits = maskbits << (8 - src_bit - bps); 
      buff1 = ((*src) & matchbits) << (src_bit);
      if ((col == start) && (sindex == sample))
        buff2 = *src & ((uint8)-1) << (shift);

      /* If we have a full buffer's worth, write it out */
      if (ready_bits >= 8)
        {
        *dst++ |= buff2;
        buff2 = buff1;
        ready_bits -= 8;
        }
      else
	buff2 = buff2 | (buff1 >> ready_bits);
      ready_bits += bps;
      }
    }

  while (ready_bits > 0)
    {
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
    *dst++ = buff1;
    ready_bits -= 8;
    }

  return (0);
  } /* end extractContigSamplesShifted8bits */

Project: libtiff

extractContigSamplesToBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
  	                     tsample_t sample, uint16 spp, uint16 bps, 
                             struct dump_opts *dump)
  {
  int    shift_width, bytes_per_sample, bytes_per_pixel;
  uint32 src_rowsize, src_offset, row, first_col = 0;
  uint32 dst_rowsize, dst_offset;
  tsample_t count = 1;
  uint8 *src, *dst;

  bytes_per_sample = (bps + 7) / 8; 
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
  if ((bps % 8) == 0)
    shift_width = 0;
  else
    {
    if (bytes_per_pixel < (bytes_per_sample + 1))
      shift_width = bytes_per_pixel;
    else
      shift_width = bytes_per_sample + 1;
    }
  src_rowsize = ((bps * spp * cols) + 7) / 8;
  dst_rowsize = ((bps * cols) + 7) / 8;

  if ((dump->outfile != NULL) && (dump->level == 4))
    {
    dump_info  (dump->outfile, dump->format, "extractContigSamplesToBuffer", 
                "Sample %d, %d rows", sample + 1, rows + 1);
    }
  for (row = 0; row < rows; row++)
    {
    src_offset = row * src_rowsize;
    dst_offset = row * dst_rowsize;
    src = in + src_offset;
    dst = out + dst_offset;

    /* pack the data into the scanline */
    switch (shift_width)
      {  
      case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
                                             spp, bps,  count, first_col, cols))  
                return (1);
 	      break;
      case 1: if (bps == 1)
                {
                if (extractContigSamples8bits (src, dst, cols, sample,
                                               spp, bps, count, first_col, cols))
	          return (1);
	        break;
		}
	      else
                 if (extractContigSamples16bits (src, dst, cols, sample,
                                                 spp, bps, count, first_col, cols))
	         return (1);
	      break;
      case 2: if (extractContigSamples24bits (src, dst, cols, sample,
                                              spp, bps,  count, first_col, cols))
	         return (1);
	      break;
      case 3:
      case 4: 
      case 5: if (extractContigSamples32bits (src, dst, cols, sample,
                                              spp, bps,  count, first_col, cols))
	         return (1);
	      break;
      default: TIFFError ("extractContigSamplesToBuffer", "Unsupported bit depth: %d", bps);
	       return (1);
      }
    if ((dump->outfile != NULL) && (dump->level == 4))
      dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
    }

  return (0);
  } /* end extractContigSamplesToBuffer */

Project: libtiff

extractContigSamplesToTileBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols,
  	                         uint32 imagewidth, uint32 tilewidth, tsample_t sample,
				 uint16 count, uint16 spp, uint16 bps, struct dump_opts *dump)
  {
  int    shift_width, bytes_per_sample, bytes_per_pixel;
  uint32 src_rowsize, src_offset, row;
  uint32 dst_rowsize, dst_offset;
  uint8 *src, *dst;

  bytes_per_sample = (bps + 7) / 8; 
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
  if ((bps % 8) == 0)
    shift_width = 0;
  else
    {
    if (bytes_per_pixel < (bytes_per_sample + 1))
      shift_width = bytes_per_pixel;
    else
      shift_width = bytes_per_sample + 1;
    }

  if ((dump->outfile != NULL) && (dump->level == 4))
    {
    dump_info  (dump->outfile, dump->format, "extractContigSamplesToTileBuffer", 
                "Sample %d, %d rows", sample + 1, rows + 1);
    }

  src_rowsize = ((bps * spp * imagewidth) + 7) / 8;
  dst_rowsize = ((bps * tilewidth * count) + 7) / 8;

  for (row = 0; row < rows; row++)
    {
    src_offset = row * src_rowsize;
    dst_offset = row * dst_rowsize;
    src = in + src_offset;
    dst = out + dst_offset;

    /* pack the data into the scanline */
    switch (shift_width)
      {  
      case 0: if (extractContigSamplesBytes (src, dst, cols, sample,
                                             spp, bps,  count, 0, cols))  
                return (1);
 	      break;
      case 1: if (bps == 1)
                {
                if (extractContigSamples8bits (src, dst, cols, sample,
                                               spp, bps, count, 0, cols))
	          return (1);
	        break;
		}
	      else
                 if (extractContigSamples16bits (src, dst, cols, sample,
                                                 spp, bps, count, 0, cols))
	         return (1);
	      break;
      case 2: if (extractContigSamples24bits (src, dst, cols, sample,
                                              spp, bps,  count, 0, cols))
	         return (1);
	      break;
      case 3:
      case 4: 
      case 5: if (extractContigSamples32bits (src, dst, cols, sample,
                                              spp, bps,  count, 0, cols))
	         return (1);
	      break;
      default: TIFFError ("extractContigSamplesToTileBuffer", "Unsupported bit depth: %d", bps);
	       return (1);
      }
    if ((dump->outfile != NULL) && (dump->level == 4))
      dump_buffer(dump->outfile, dump->format, 1, dst_rowsize, row, dst);
    }

  return (0);
  } /* end extractContigSamplesToTileBuffer */

Project: libtiff

extractImageSection(struct image_data *image, struct pageseg *section, 
                    unsigned char *src_buff, unsigned char *sect_buff)
  {
  unsigned  char  bytebuff1, bytebuff2;
#ifdef DEVELMODE
  /* unsigned  char *src, *dst; */
#endif

  uint32    img_width, img_rowsize;
#ifdef DEVELMODE
  uint32    img_length;
#endif
  uint32    j, shift1, shift2, trailing_bits;
  uint32    row, first_row, last_row, first_col, last_col;
  uint32    src_offset, dst_offset, row_offset, col_offset;
  uint32    offset1, offset2, full_bytes;
  uint32    sect_width;
#ifdef DEVELMODE
  uint32    sect_length;
#endif
  uint16    bps, spp;

#ifdef DEVELMODE
  int      k;
  unsigned char bitset;
  static char *bitarray = NULL;
#endif

  img_width = image->width;
#ifdef DEVELMODE
  img_length = image->length;
#endif
  bps = image->bps;
  spp = image->spp;

#ifdef DEVELMODE
  /* src = src_buff; */
  /* dst = sect_buff; */
#endif
  src_offset = 0;
  dst_offset = 0;

#ifdef DEVELMODE
  if (bitarray == NULL)
    {
    if ((bitarray = (char *)malloc(img_width)) == NULL)
      {
      TIFFError ("", "DEBUG: Unable to allocate debugging bitarray");
      return (-1);
      }
    }
#endif

  /* rows, columns, width, length are expressed in pixels */
  first_row = section->y1;
  last_row  = section->y2;
  first_col = section->x1;
  last_col  = section->x2;

  sect_width = last_col - first_col + 1;
#ifdef DEVELMODE
  sect_length = last_row - first_row + 1;
#endif
  img_rowsize = ((img_width * bps + 7) / 8) * spp;
  full_bytes = (sect_width * spp * bps) / 8;   /* number of COMPLETE bytes per row in section */
  trailing_bits = (sect_width * bps) % 8;

#ifdef DEVELMODE
    TIFFError ("", "First row: %d, last row: %d, First col: %d, last col: %d\n",
           first_row, last_row, first_col, last_col);
    TIFFError ("", "Image width: %d, Image length: %d, bps: %d, spp: %d\n",
	   img_width, img_length, bps, spp);
    TIFFError ("", "Sect  width: %d,  Sect length: %d, full bytes: %d trailing bits %d\n", 
           sect_width, sect_length, full_bytes, trailing_bits);
#endif

  if ((bps % 8) == 0)
    {
    col_offset = first_col * spp * bps / 8;
    for (row = first_row; row <= last_row; row++)
      {
      /* row_offset = row * img_width * spp * bps / 8; */
      row_offset = row * img_rowsize;
      src_offset = row_offset + col_offset;

#ifdef DEVELMODE
        TIFFError ("", "Src offset: %8d, Dst offset: %8d", src_offset, dst_offset); 
#endif
      _TIFFmemcpy (sect_buff + dst_offset, src_buff + src_offset, full_bytes);
      dst_offset += full_bytes;
      }        
    }
  else
    { /* bps != 8 */
    shift1  = spp * ((first_col * bps) % 8);
    shift2  = spp * ((last_col * bps) % 8);
    for (row = first_row; row <= last_row; row++)
      {
      /* pull out the first byte */
      row_offset = row * img_rowsize;
      offset1 = row_offset + (first_col * bps / 8);
      offset2 = row_offset + (last_col * bps / 8);

#ifdef DEVELMODE
      for (j = 0, k = 7; j < 8; j++, k--)
        {
        bitset = *(src_buff + offset1) & (((unsigned char)1 << k)) ? 1 : 0;
        sprintf(&bitarray[j], (bitset) ? "1" : "0");
        }
      sprintf(&bitarray[8], " ");
      sprintf(&bitarray[9], " ");
      for (j = 10, k = 7; j < 18; j++, k--)
        {
        bitset = *(src_buff + offset2) & (((unsigned char)1 << k)) ? 1 : 0;
        sprintf(&bitarray[j], (bitset) ? "1" : "0");
        }
      bitarray[18] = '\0';
      TIFFError ("", "Row: %3d Offset1: %d,  Shift1: %d,    Offset2: %d,  Shift2:  %d\n", 
                 row, offset1, shift1, offset2, shift2); 
#endif

      bytebuff1 = bytebuff2 = 0;
      if (shift1 == 0) /* the region is byte and sample alligned */
        {
	_TIFFmemcpy (sect_buff + dst_offset, src_buff + offset1, full_bytes);

#ifdef DEVELMODE
	TIFFError ("", "        Alligned data src offset1: %8d, Dst offset: %8d\n", offset1, dst_offset); 
	sprintf(&bitarray[18], "\n");
	sprintf(&bitarray[19], "\t");
        for (j = 20, k = 7; j < 28; j++, k--)
          {
          bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
          sprintf(&bitarray[j], (bitset) ? "1" : "0");
          }
        bitarray[28] = ' ';
        bitarray[29] = ' ';
#endif
        dst_offset += full_bytes;

        if (trailing_bits != 0)
          {
	  bytebuff2 = src_buff[offset2] & ((unsigned char)255 << (7 - shift2));
          sect_buff[dst_offset] = bytebuff2;
#ifdef DEVELMODE
	  TIFFError ("", "        Trailing bits src offset:  %8d, Dst offset: %8d\n", 
                              offset2, dst_offset); 
          for (j = 30, k = 7; j < 38; j++, k--)
            {
            bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
            sprintf(&bitarray[j], (bitset) ? "1" : "0");
            }
          bitarray[38] = '\0';
          TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
#endif
          dst_offset++;
          }
        }
      else   /* each destination byte will have to be built from two source bytes*/
        {
#ifdef DEVELMODE
	  TIFFError ("", "        Unalligned data src offset: %8d, Dst offset: %8d\n", offset1 , dst_offset); 
#endif
        for (j = 0; j <= full_bytes; j++) 
          {
	  bytebuff1 = src_buff[offset1 + j] & ((unsigned char)255 >> shift1);
	  bytebuff2 = src_buff[offset1 + j + 1] & ((unsigned char)255 << (7 - shift1));
          sect_buff[dst_offset + j] = (bytebuff1 << shift1) | (bytebuff2 >> (8 - shift1));
          }
#ifdef DEVELMODE
	sprintf(&bitarray[18], "\n");
	sprintf(&bitarray[19], "\t");
        for (j = 20, k = 7; j < 28; j++, k--)
          {
          bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
          sprintf(&bitarray[j], (bitset) ? "1" : "0");
          }
        bitarray[28] = ' ';
        bitarray[29] = ' ';
#endif
        dst_offset += full_bytes;

        if (trailing_bits != 0)
          {
#ifdef DEVELMODE
	    TIFFError ("", "        Trailing bits   src offset: %8d, Dst offset: %8d\n", offset1 + full_bytes, dst_offset); 
#endif
	  if (shift2 > shift1)
            {
	    bytebuff1 = src_buff[offset1 + full_bytes] & ((unsigned char)255 << (7 - shift2));
            bytebuff2 = bytebuff1 & ((unsigned char)255 << shift1);
            sect_buff[dst_offset] = bytebuff2;
#ifdef DEVELMODE
	    TIFFError ("", "        Shift2 > Shift1\n"); 
#endif
            }
          else
            {
	    if (shift2 < shift1)
              {
              bytebuff2 = ((unsigned char)255 << (shift1 - shift2 - 1));
	      sect_buff[dst_offset] &= bytebuff2;
#ifdef DEVELMODE
	      TIFFError ("", "        Shift2 < Shift1\n"); 
#endif
              }
#ifdef DEVELMODE
            else
	      TIFFError ("", "        Shift2 == Shift1\n"); 
#endif
            }
	  }
#ifdef DEVELMODE
	  sprintf(&bitarray[28], " ");
	  sprintf(&bitarray[29], " ");
          for (j = 30, k = 7; j < 38; j++, k--)
            {
            bitset = *(sect_buff + dst_offset) & (((unsigned char)1 << k)) ? 1 : 0;
            sprintf(&bitarray[j], (bitset) ? "1" : "0");
            }
          bitarray[38] = '\0';
          TIFFError ("", "\tFirst and last bytes before and after masking:\n\t%s\n\n", bitarray);
#endif
        dst_offset++;
        }
      }
    }

  return (0);
  } /* end extractImageSection */

Project: libtiff

getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opts *dump)
  {
  struct offset offsets;
  int    i;
  int32  test;
  uint32 seg, total, need_buff = 0;
  uint32 buffsize;
  uint32 zwidth, zlength;

  memset(&offsets, '\0', sizeof(struct offset));
  crop->bufftotal = 0;
  crop->combined_width  = (uint32)0;
  crop->combined_length = (uint32)0;
  crop->selections = 0;

  /* Compute pixel offsets if margins or fixed width or length specified */
  if ((crop->crop_mode & CROP_MARGINS) ||
      (crop->crop_mode & CROP_REGIONS) ||
      (crop->crop_mode & CROP_LENGTH)  || 
      (crop->crop_mode & CROP_WIDTH))
    {
    if (computeInputPixelOffsets(crop, image, &offsets))
      {
      TIFFError ("getCropOffsets", "Unable to compute crop margins");
      return (-1);
      }
    need_buff = TRUE;
    crop->selections = crop->regions;
    /* Regions are only calculated from top and left edges with no margins */
    if (crop->crop_mode & CROP_REGIONS)
      return (0);
    }
  else
    { /* cropped area is the full image */
    offsets.tmargin = 0;
    offsets.lmargin = 0;
    offsets.bmargin = 0;
    offsets.rmargin = 0;
    offsets.crop_width = image->width;
    offsets.crop_length = image->length;
    offsets.startx = 0;
    offsets.endx = image->width - 1;
    offsets.starty = 0;
    offsets.endy = image->length - 1;
    need_buff = FALSE;
    }

  if (dump->outfile != NULL)
    {
    dump_info (dump->outfile, dump->format, "", "Margins: Top: %d  Left: %d  Bottom: %d  Right: %d", 
           offsets.tmargin, offsets.lmargin, offsets.bmargin, offsets.rmargin); 
    dump_info (dump->outfile, dump->format, "", "Crop region within margins: Adjusted Width:  %6d  Length: %6d", 
           offsets.crop_width, offsets.crop_length);
    }

  if (!(crop->crop_mode & CROP_ZONES)) /* no crop zones requested */
    {
    if (need_buff == FALSE)  /* No margins or fixed width or length areas */
      {
      crop->selections = 0;
      crop->combined_width  = image->width;
      crop->combined_length = image->length;
      return (0);
      }
    else 
      {
      /* Use one region for margins and fixed width or length areas
       * even though it was not formally declared as a region.
       */
      crop->selections = 1;
      crop->zones = 1;
      crop->zonelist[0].total = 1;
      crop->zonelist[0].position = 1;
      }
    }     
  else
    crop->selections = crop->zones;

  for (i = 0; i < crop->zones; i++)
    {
    seg = crop->zonelist[i].position;
    total = crop->zonelist[i].total;

    switch (crop->edge_ref) 
      {
      case EDGE_LEFT: /* zones from left to right, length from top */
           zlength = offsets.crop_length;
	   crop->regionlist[i].y1 = offsets.starty;
           crop->regionlist[i].y2 = offsets.endy;

           crop->regionlist[i].x1 = offsets.startx + 
                                  (uint32)(offsets.crop_width * 1.0 * (seg - 1) / total);
           test = (int32)offsets.startx + 
                  (int32)(offsets.crop_width * 1.0 * seg / total);
           if (test < 1 )
             crop->regionlist[i].x2 = 0;
           else
	     {
	     if (test > (int32)(image->width - 1))
               crop->regionlist[i].x2 = image->width - 1;
             else
	       crop->regionlist[i].x2 = test - 1;
             }
           zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1  + 1;

	   /* This is passed to extractCropZone or extractCompositeZones */
           crop->combined_length = (uint32)zlength;
           if (crop->exp_mode == COMPOSITE_IMAGES)
             crop->combined_width += (uint32)zwidth;
           else
             crop->combined_width = (uint32)zwidth;
           break;
      case EDGE_BOTTOM: /* width from left, zones from bottom to top */
           zwidth = offsets.crop_width;
	   crop->regionlist[i].x1 = offsets.startx;
           crop->regionlist[i].x2 = offsets.endx;

           test = offsets.endy - (uint32)(offsets.crop_length * 1.0 * seg / total);
           if (test < 1 )
	     crop->regionlist[i].y1 = 0;
           else
	     crop->regionlist[i].y1 = test + 1;

           test = offsets.endy - (offsets.crop_length * 1.0 * (seg - 1) / total);
           if (test < 1 )
             crop->regionlist[i].y2 = 0;
           else
	     {
             if (test > (int32)(image->length - 1))
               crop->regionlist[i].y2 = image->length - 1;
             else 
               crop->regionlist[i].y2 = test;
	     }
           zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;

	   /* This is passed to extractCropZone or extractCompositeZones */
           if (crop->exp_mode == COMPOSITE_IMAGES)
             crop->combined_length += (uint32)zlength;
           else
             crop->combined_length = (uint32)zlength;
           crop->combined_width = (uint32)zwidth;
           break;
      case EDGE_RIGHT: /* zones from right to left, length from top */
           zlength = offsets.crop_length;
	   crop->regionlist[i].y1 = offsets.starty;
           crop->regionlist[i].y2 = offsets.endy;

           crop->regionlist[i].x1 = offsets.startx +
                                  (uint32)(offsets.crop_width  * (total - seg) * 1.0 / total);
           test = offsets.startx + 
	          (offsets.crop_width * (total - seg + 1) * 1.0 / total);
           if (test < 1 )
             crop->regionlist[i].x2 = 0;
           else
	     {
	     if (test > (int32)(image->width - 1))
               crop->regionlist[i].x2 = image->width - 1;
             else
               crop->regionlist[i].x2 = test - 1;
             }
           zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1  + 1;

	   /* This is passed to extractCropZone or extractCompositeZones */
           crop->combined_length = (uint32)zlength;
           if (crop->exp_mode == COMPOSITE_IMAGES)
             crop->combined_width += (uint32)zwidth;
           else
             crop->combined_width = (uint32)zwidth;
           break;
      case EDGE_TOP: /* width from left, zones from top to bottom */
      default:
           zwidth = offsets.crop_width;
	   crop->regionlist[i].x1 = offsets.startx;
           crop->regionlist[i].x2 = offsets.endx;

           crop->regionlist[i].y1 = offsets.starty + (uint32)(offsets.crop_length * 1.0 * (seg - 1) / total);
           test = offsets.starty + (uint32)(offsets.crop_length * 1.0 * seg / total);
           if (test < 1 )
             crop->regionlist[i].y2 = 0;
           else
	     {
	     if (test > (int32)(image->length - 1))
	       crop->regionlist[i].y2 = image->length - 1;
             else
	       crop->regionlist[i].y2 = test - 1;
	     }
           zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;

	   /* This is passed to extractCropZone or extractCompositeZones */
           if (crop->exp_mode == COMPOSITE_IMAGES)
             crop->combined_length += (uint32)zlength;
           else
             crop->combined_length = (uint32)zlength;
           crop->combined_width = (uint32)zwidth;
           break;
      } /* end switch statement */

    buffsize = (uint32)
          ((((zwidth * image->bps * image->spp) + 7 ) / 8) * (zlength + 1));
    crop->regionlist[i].width = (uint32) zwidth;
    crop->regionlist[i].length = (uint32) zlength;
    crop->regionlist[i].buffsize = buffsize;
    crop->bufftotal += buffsize;


  if (dump->outfile != NULL)
    dump_info (dump->outfile, dump->format, "",  "Zone %d, width: %4d, length: %4d, x1: %4d  x2: %4d  y1: %4d  y2: %4d",
                    i + 1, (uint32)zwidth, (uint32)zlength,
		    crop->regionlist[i].x1, crop->regionlist[i].x2, 
                    crop->regionlist[i].y1, crop->regionlist[i].y2);
    }

  return (0);
  } /* end getCropOffsets */

Project: libtiff

get_page_geometry (char *name, struct pagedef *page)
    {
    char *ptr;
    int n; 

    for (ptr = name; *ptr; ptr++)
      *ptr = (char)tolower((int)*ptr);

    for (n = 0; n < MAX_PAPERNAMES; n++)
      {
      if (strcmp(name, PaperTable[n].name) == 0)
        {
	page->width = PaperTable[n].width;
	page->length = PaperTable[n].length;
        strncpy (page->name, PaperTable[n].name, 15);
        page->name[15] = '\0';
        return (0);
        }
      }

  return (1);
  }

Project: libtiff

initCropMasks (struct crop_mask *cps)
   {
   int i;

   cps->crop_mode = CROP_NONE;
   cps->res_unit  = RESUNIT_NONE;
   cps->edge_ref  = EDGE_TOP;
   cps->width = 0;
   cps->length = 0;
   for (i = 0; i < 4; i++)
     cps->margins[i] = 0.0;
   cps->bufftotal = (uint32)0;
   cps->combined_width = (uint32)0;
   cps->combined_length = (uint32)0;
   cps->rotation = (uint16)0;
   cps->photometric = INVERT_DATA_AND_TAG;
   cps->mirror   = (uint16)0;
   cps->invert   = (uint16)0;
   cps->zones    = (uint32)0;
   cps->regions  = (uint32)0;
   for (i = 0; i < MAX_REGIONS; i++)
     {
     cps->corners[i].X1 = 0.0;
     cps->corners[i].X2 = 0.0;
     cps->corners[i].Y1 = 0.0;
     cps->corners[i].Y2 = 0.0;
     cps->regionlist[i].x1 = 0;
     cps->regionlist[i].x2 = 0;
     cps->regionlist[i].y1 = 0;
     cps->regionlist[i].y2 = 0;
     cps->regionlist[i].width = 0;
     cps->regionlist[i].length = 0;
     cps->regionlist[i].buffsize = 0;
     cps->regionlist[i].buffptr = NULL;
     cps->zonelist[i].position = 0;
     cps->zonelist[i].total = 0;
     }
   cps->exp_mode = ONE_FILE_COMPOSITE;
   cps->img_mode = COMPOSITE_IMAGES;
   }

Project: libtiff

static void initDumpOptions(struct dump_opts *dump)
  {
  dump->debug  = 0;
  dump->format = DUMP_NONE;
  dump->level  = 1;
  sprintf (dump->mode, "w");
  memset (dump->infilename, '\0', PATH_MAX + 1);
  memset (dump->outfilename, '\0',PATH_MAX + 1);
  dump->infile = NULL;
  dump->outfile = NULL;
  }

Project: libtiff

initImageData (struct image_data *image)
  {
  image->xres = 0.0;
  image->yres = 0.0;
  image->width = 0;
  image->length = 0;
  image->res_unit = RESUNIT_NONE;
  image->bps = 0;
  image->spp = 0;
  image->planar = 0;
  image->photometric = 0;
  image->orientation = 0;
  image->compression = COMPRESSION_NONE;
  image->adjustments = 0;
  }

Project: libtiff

initPageSetup (struct pagedef *page, struct pageseg *pagelist, 
               struct buffinfo seg_buffs[])
   {
   int i; 

   strcpy (page->name, "");
   page->mode = PAGE_MODE_NONE;
   page->res_unit = RESUNIT_NONE;
   page->hres = 0.0;
   page->vres = 0.0;
   page->width = 0.0;
   page->length = 0.0;
   page->hmargin = 0.0;
   page->vmargin = 0.0;
   page->rows = 0;
   page->cols = 0;
   page->orient = ORIENTATION_NONE;

   for (i = 0; i < MAX_SECTIONS; i++)
     {
     pagelist[i].x1 = (uint32)0;
     pagelist[i].x2 = (uint32)0;
     pagelist[i].y1 = (uint32)0;
     pagelist[i].y2 = (uint32)0;
     pagelist[i].buffsize = (uint32)0;
     pagelist[i].position = 0;
     pagelist[i].total = 0;
     }

   for (i = 0; i < MAX_OUTBUFFS; i++)
     {
     seg_buffs[i].size = 0;
     seg_buffs[i].buffer = NULL;
     }
   }

Project: libtiff

loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned char **read_ptr)
  {
  uint32   i;
  float    xres = 0.0, yres = 0.0;
  uint32   nstrips = 0, ntiles = 0;
  uint16   planar = 0;
  uint16   bps = 0, spp = 0, res_unit = 0;
  uint16   orientation = 0;
  uint16   input_compression = 0, input_photometric = 0;
  uint16   subsampling_horiz, subsampling_vert;
  uint32   width = 0, length = 0;
  uint32   stsize = 0, tlsize = 0, buffsize = 0, scanlinesize = 0;
  uint32   tw = 0, tl = 0;       /* Tile width and length */
  uint32   tile_rowsize = 0;
  unsigned char *read_buff = NULL;
  unsigned char *new_buff  = NULL;
  int      readunit = 0;
  static   uint32  prev_readsize = 0;

  TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
  TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
  TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
  TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
  if (! TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric))
    TIFFError("loadImage","Image lacks Photometric interpreation tag");
  if (! TIFFGetField(in, TIFFTAG_IMAGEWIDTH,  &width))
    TIFFError("loadimage","Image lacks image width tag");
  if(! TIFFGetField(in, TIFFTAG_IMAGELENGTH, &length))
    TIFFError("loadimage","Image lacks image length tag");
  TIFFGetFieldDefaulted(in, TIFFTAG_XRESOLUTION, &xres);
  TIFFGetFieldDefaulted(in, TIFFTAG_YRESOLUTION, &yres);
  if (!TIFFGetFieldDefaulted(in, TIFFTAG_RESOLUTIONUNIT, &res_unit))
    res_unit = RESUNIT_INCH;
  if (!TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression))
    input_compression = COMPRESSION_NONE;

#ifdef DEBUG2
  char compressionid[16];

  switch (input_compression)
    {
    case COMPRESSION_NONE:	/* 1  dump mode */
	 strcpy (compressionid, "None/dump");
         break;         
    case COMPRESSION_CCITTRLE:	  /* 2 CCITT modified Huffman RLE */
	 strcpy (compressionid, "Huffman RLE");
         break;         
    case COMPRESSION_CCITTFAX3:	  /* 3 CCITT Group 3 fax encoding */
	 strcpy (compressionid, "Group3 Fax");
         break;         
    case COMPRESSION_CCITTFAX4:	  /* 4 CCITT Group 4 fax encoding */
	 strcpy (compressionid, "Group4 Fax");
         break;         
    case COMPRESSION_LZW:	  /* 5 Lempel-Ziv  & Welch */
	 strcpy (compressionid, "LZW");
         break;         
    case COMPRESSION_OJPEG:	  /* 6 !6.0 JPEG */
	 strcpy (compressionid, "Old Jpeg");
         break;         
    case COMPRESSION_JPEG:	  /* 7 %JPEG DCT compression */
	 strcpy (compressionid, "New Jpeg");
         break;         
    case COMPRESSION_NEXT:	  /* 32766 NeXT 2-bit RLE */
	 strcpy (compressionid, "Next RLE");
         break;         
    case COMPRESSION_CCITTRLEW:   /* 32771 #1 w/ word alignment */
	 strcpy (compressionid, "CITTRLEW");
         break;         
    case COMPRESSION_PACKBITS:	  /* 32773 Macintosh RLE */
	 strcpy (compressionid, "Mac Packbits");
         break;         
    case COMPRESSION_THUNDERSCAN: /* 32809 ThunderScan RLE */
	 strcpy (compressionid, "Thunderscan");
         break;         
    case COMPRESSION_IT8CTPAD:	  /* 32895 IT8 CT w/padding */
	 strcpy (compressionid, "IT8 padded");
         break;         
    case COMPRESSION_IT8LW:	  /* 32896 IT8 Linework RLE */
	 strcpy (compressionid, "IT8 RLE");
         break;         
    case COMPRESSION_IT8MP:	  /* 32897 IT8 Monochrome picture */
	 strcpy (compressionid, "IT8 mono");
         break;         
    case COMPRESSION_IT8BL:	  /* 32898 IT8 Binary line art */
	 strcpy (compressionid, "IT8 lineart");
         break;         
    case COMPRESSION_PIXARFILM:	  /* 32908 Pixar companded 10bit LZW */
	 strcpy (compressionid, "Pixar 10 bit");
         break;         
    case COMPRESSION_PIXARLOG:	  /* 32909 Pixar companded 11bit ZIP */
	 strcpy (compressionid, "Pixar 11bit");
         break;         
    case COMPRESSION_DEFLATE:	  /* 32946 Deflate compression */
	 strcpy (compressionid, "Deflate");
         break;         
    case COMPRESSION_ADOBE_DEFLATE: /* 8 Deflate compression */
	 strcpy (compressionid, "Adobe deflate");
         break;         
    default:
	 strcpy (compressionid, "None/unknown");
         break;         
    }
  TIFFError("loadImage", "Input compression %s", compressionid);
#endif

  scanlinesize = TIFFScanlineSize(in);
  image->bps = bps;
  image->spp = spp;
  image->planar = planar;
  image->width = width;
  image->length = length;
  image->xres = xres;
  image->yres = yres;
  image->res_unit = res_unit;
  image->compression = input_compression;
  image->photometric = input_photometric;
#ifdef DEBUG2
  char photometricid[12];

  switch (input_photometric)
    {
    case PHOTOMETRIC_MINISWHITE:
         strcpy (photometricid, "MinIsWhite");
         break;
    case PHOTOMETRIC_MINISBLACK:
         strcpy (photometricid, "MinIsBlack");
         break;
    case PHOTOMETRIC_RGB:
         strcpy (photometricid, "RGB");
         break;
    case PHOTOMETRIC_PALETTE:
         strcpy (photometricid, "Palette");
         break;
    case PHOTOMETRIC_MASK:
         strcpy (photometricid, "Mask");
         break;
    case PHOTOMETRIC_SEPARATED:
         strcpy (photometricid, "Separated");
         break;
    case PHOTOMETRIC_YCBCR:
         strcpy (photometricid, "YCBCR");
         break;
    case PHOTOMETRIC_CIELAB:
         strcpy (photometricid, "CIELab");
         break;
    case PHOTOMETRIC_ICCLAB:
         strcpy (photometricid, "ICCLab");
         break;
    case PHOTOMETRIC_ITULAB:
         strcpy (photometricid, "ITULab");
         break;
    case PHOTOMETRIC_LOGL:
         strcpy (photometricid, "LogL");
         break;
    case PHOTOMETRIC_LOGLUV:
         strcpy (photometricid, "LOGLuv");
         break;
    default:
         strcpy (photometricid, "Unknown");
         break;
    }
  TIFFError("loadImage", "Input photometric interpretation %s", photometricid);

#endif
  image->orientation = orientation;
  switch (orientation)
    {
    case 0:
    case ORIENTATION_TOPLEFT:
         image->adjustments = 0;
	 break;
    case ORIENTATION_TOPRIGHT:
         image->adjustments = MIRROR_HORIZ;
	 break;
    case ORIENTATION_BOTRIGHT:
         image->adjustments = ROTATECW_180;
	 break;
    case ORIENTATION_BOTLEFT:
         image->adjustments = MIRROR_VERT; 
	 break;
    case ORIENTATION_LEFTTOP:
         image->adjustments = MIRROR_VERT | ROTATECW_90;
	 break;
    case ORIENTATION_RIGHTTOP:
         image->adjustments = ROTATECW_90;
	 break;
    case ORIENTATION_RIGHTBOT:
         image->adjustments = MIRROR_VERT | ROTATECW_270;
	 break; 
    case ORIENTATION_LEFTBOT:
         image->adjustments = ROTATECW_270;
	 break;
    default:
         image->adjustments = 0;
         image->orientation = ORIENTATION_TOPLEFT;
   }

  if ((bps == 0) || (spp == 0))
    {
    TIFFError("loadImage", "Invalid samples per pixel (%d) or bits per sample (%d)",
	       spp, bps);
    return (-1);
    }

  if (TIFFIsTiled(in))
    {
    readunit = TILE;
    tlsize = TIFFTileSize(in);
    ntiles = TIFFNumberOfTiles(in);
    TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
    TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);

    tile_rowsize  = TIFFTileRowSize(in);      
    if (ntiles == 0 || tlsize == 0 || tile_rowsize == 0)
    {
	TIFFError("loadImage", "File appears to be tiled, but the number of tiles, tile size, or tile rowsize is zero.");
	exit(-1);
    }
    buffsize = tlsize * ntiles;
    if (tlsize != (buffsize / ntiles))
    {
	TIFFError("loadImage", "Integer overflow when calculating buffer size");
	exit(-1);
    }

    if (buffsize < (uint32)(ntiles * tl * tile_rowsize))
      {
      buffsize = ntiles * tl * tile_rowsize;
      if (ntiles != (buffsize / tl / tile_rowsize))
      {
	TIFFError("loadImage", "Integer overflow when calculating buffer size");
	exit(-1);
      }
      
#ifdef DEBUG2
      TIFFError("loadImage",
	        "Tilesize %u is too small, using ntiles * tilelength * tilerowsize %lu",
                tlsize, (unsigned long)buffsize);
#endif
      }
    
    if (dump->infile != NULL)
      dump_info (dump->infile, dump->format, "", 
                 "Tilesize: %u, Number of Tiles: %u, Tile row size: %u",
                 tlsize, ntiles, tile_rowsize);
    }
  else
    {
    uint32 buffsize_check;
    readunit = STRIP;
    TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
    stsize = TIFFStripSize(in);
    nstrips = TIFFNumberOfStrips(in);
    if (nstrips == 0 || stsize == 0)
    {
	TIFFError("loadImage", "File appears to be striped, but the number of stipes or stripe size is zero.");
	exit(-1);
    }

    buffsize = stsize * nstrips;
    if (stsize != (buffsize / nstrips))
    {
	TIFFError("loadImage", "Integer overflow when calculating buffer size");
	exit(-1);
    }
    buffsize_check = ((length * width * spp * bps) + 7);
    if (length != ((buffsize_check - 7) / width / spp / bps))
    {
	TIFFError("loadImage", "Integer overflow detected.");
	exit(-1);
    }
    if (buffsize < (uint32) (((length * width * spp * bps) + 7) / 8))
      {
      buffsize =  ((length * width * spp * bps) + 7) / 8;
#ifdef DEBUG2
      TIFFError("loadImage",
	        "Stripsize %u is too small, using imagelength * width * spp * bps / 8 = %lu",
                stsize, (unsigned long)buffsize);
#endif
      }
    
    if (dump->infile != NULL)
      dump_info (dump->infile, dump->format, "",
                 "Stripsize: %u, Number of Strips: %u, Rows per Strip: %u, Scanline size: %u",
		 stsize, nstrips, rowsperstrip, scanlinesize);
    }
  
  if (input_compression == COMPRESSION_JPEG)
    {  /* Force conversion to RGB */
    jpegcolormode = JPEGCOLORMODE_RGB;
    TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
    }
  /* The clause up to the read statement is taken from Tom Lane's tiffcp patch */
  else 
    {   /* Otherwise, can't handle subsampled input */
    if (input_photometric == PHOTOMETRIC_YCBCR)
      {
      TIFFGetFieldDefaulted(in, TIFFTAG_YCBCRSUBSAMPLING,
 		           &subsampling_horiz, &subsampling_vert);
      if (subsampling_horiz != 1 || subsampling_vert != 1)
        {
	TIFFError("loadImage", 
		"Can't copy/convert subsampled image with subsampling %d horiz %d vert",
                subsampling_horiz, subsampling_vert);
        return (-1);
        }
	}
    }
 
  read_buff = *read_ptr;
  /* +3 : add a few guard bytes since reverseSamples16bits() can read a bit */
  /* outside buffer */
  if (!read_buff)
  {
    if( buffsize > 0xFFFFFFFFU - 3 )
    {
        TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
        return (-1);
    }
    read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
  }
  else
    {
    if (prev_readsize < buffsize)
    {
      if( buffsize > 0xFFFFFFFFU - 3 )
      {
          TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
          return (-1);
      }
      new_buff = _TIFFrealloc(read_buff, buffsize+3);
      if (!new_buff)
        {
	free (read_buff);
        read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
        }
      else
        read_buff = new_buff;
      }
    }
  if (!read_buff)
    {
    TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
    return (-1);
    }

  read_buff[buffsize] = 0;
  read_buff[buffsize+1] = 0;
  read_buff[buffsize+2] = 0;

  prev_readsize = buffsize;
  *read_ptr = read_buff;

  /* N.B. The read functions used copy separate plane data into a buffer as interleaved
   * samples rather than separate planes so the same logic works to extract regions
   * regardless of the way the data are organized in the input file.
   */
  switch (readunit) {
    case STRIP:
         if (planar == PLANARCONFIG_CONTIG)
           {
	     if (!(readContigStripsIntoBuffer(in, read_buff)))
	     {
	     TIFFError("loadImage", "Unable to read contiguous strips into buffer");
	     return (-1);
             }
           }
         else
           {
	   if (!(readSeparateStripsIntoBuffer(in, read_buff, length, width, spp, dump)))
	     {
	     TIFFError("loadImage", "Unable to read separate strips into buffer");
	     return (-1);
             }
           }
         break;

    case TILE:
         if (planar == PLANARCONFIG_CONTIG)
           {
	   if (!(readContigTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
	     {
	     TIFFError("loadImage", "Unable to read contiguous tiles into buffer");
	     return (-1);
             }
           }
         else
           {
	   if (!(readSeparateTilesIntoBuffer(in, read_buff, length, width, tw, tl, spp, bps)))
	     {
	     TIFFError("loadImage", "Unable to read separate tiles into buffer");
	     return (-1);
             }
           }
         break;
    default: TIFFError("loadImage", "Unsupported image file format");
          return (-1);
          break;
    }
  if ((dump->infile != NULL) && (dump->level == 2))
    {
    dump_info  (dump->infile, dump->format, "loadImage", 
                "Image width %d, length %d, Raw image data, %4d bytes",
                width, length,  buffsize);
    dump_info  (dump->infile, dump->format, "", 
                "Bits per sample %d, Samples per pixel %d", bps, spp);

    for (i = 0; i < length; i++)
      dump_buffer(dump->infile, dump->format, 1, scanlinesize, 
                  i, read_buff + (i * scanlinesize));
    }
  return (0);
  }   /* end loadImage */

Project: libtiff

main(int argc, char* argv[])
  {

#if !HAVE_DECL_OPTARG
  extern int optind;
#endif
  uint16 defconfig = (uint16) -1;
  uint16 deffillorder = 0;
  uint32 deftilewidth = (uint32) 0;
  uint32 deftilelength = (uint32) 0;
  uint32 defrowsperstrip = (uint32) 0;
  uint32 dirnum = 0;

  TIFF *in = NULL;
  TIFF *out = NULL;
  char  mode[10];
  char *mp = mode;

  /** RJN additions **/
  struct image_data image;     /* Image parameters for one image */
  struct crop_mask  crop;      /* Cropping parameters for all images */
  struct pagedef    page;      /* Page definition for output pages */
  struct pageseg    sections[MAX_SECTIONS];  /* Sections of one output page */
  struct buffinfo   seg_buffs[MAX_SECTIONS]; /* Segment buffer sizes and pointers */
  struct dump_opts  dump;                  /* Data dump options */
  unsigned char *read_buff    = NULL;      /* Input image data buffer */
  unsigned char *crop_buff    = NULL;      /* Crop area buffer */
  unsigned char *sect_buff    = NULL;      /* Image section buffer */
  unsigned char *sect_src     = NULL;      /* Image section buffer pointer */
  unsigned int  imagelist[MAX_IMAGES + 1]; /* individually specified images */
  unsigned int  image_count  = 0;
  unsigned int  dump_images  = 0;
  unsigned int  next_image   = 0;
  unsigned int  next_page    = 0;
  unsigned int  total_pages  = 0;
  unsigned int  total_images = 0;
  unsigned int  end_of_input = FALSE;
  int    seg, length;
  char   temp_filename[PATH_MAX + 1];

  little_endian = *((unsigned char *)&little_endian) & '1';

  initImageData(&image);
  initCropMasks(&crop);
  initPageSetup(&page, sections, seg_buffs);
  initDumpOptions(&dump);

  process_command_opts (argc, argv, mp, mode, &dirnum, &defconfig, 
                        &deffillorder, &deftilewidth, &deftilelength, &defrowsperstrip,
	                &crop, &page, &dump, imagelist, &image_count);

  if (argc - optind < 2)
    usage();

  if ((argc - optind) == 2)
    pageNum = -1;
  else
    total_images = 0;
  /* read multiple input files and write to output file(s) */
  while (optind < argc - 1)
    {
    in = TIFFOpen (argv[optind], "r");
    if (in == NULL)
      return (-3);

    /* If only one input file is specified, we can use directory count */
    total_images = TIFFNumberOfDirectories(in); 
    if (image_count == 0)
      {
      dirnum = 0;
      total_pages = total_images; /* Only valid with single input file */
      }
    else
      {
      dirnum = (tdir_t)(imagelist[next_image] - 1);
      next_image++;

      /* Total pages only valid for enumerated list of pages not derived
       * using odd, even, or last keywords.
       */
      if (image_count >  total_images)
	image_count = total_images;
      
      total_pages = image_count;
      }

    /* MAX_IMAGES is used for special case "last" in selection list */
    if (dirnum == (MAX_IMAGES - 1))
      dirnum = total_images - 1;

    if (dirnum > (total_images))
      {
      TIFFError (TIFFFileName(in), 
      "Invalid image number %d, File contains only %d images", 
		 (int)dirnum + 1, total_images);
      if (out != NULL)
        (void) TIFFClose(out);
      return (1);
      }

    if (dirnum != 0 && !TIFFSetDirectory(in, (tdir_t)dirnum))
      {
      TIFFError(TIFFFileName(in),"Error, setting subdirectory at %d", dirnum);
      if (out != NULL)
        (void) TIFFClose(out);
      return (1);
      }

    end_of_input = FALSE;
    while (end_of_input == FALSE)
      {
      config = defconfig;
      compression = defcompression;
      predictor = defpredictor;
      fillorder = deffillorder;
      rowsperstrip = defrowsperstrip;
      tilewidth = deftilewidth;
      tilelength = deftilelength;
      g3opts = defg3opts;

      if (dump.format != DUMP_NONE)
        {
        /* manage input and/or output dump files here */
	dump_images++;
        length = strlen(dump.infilename);
        if (length > 0)
          {
          if (dump.infile != NULL)
            fclose (dump.infile);

          /* dump.infilename is guaranteed to be NUL termimated and have 20 bytes 
             fewer than PATH_MAX */ 
          snprintf(temp_filename, sizeof(temp_filename), "%s-read-%03d.%s",
		   dump.infilename, dump_images,
                  (dump.format == DUMP_TEXT) ? "txt" : "raw");
          if ((dump.infile = fopen(temp_filename, dump.mode)) == NULL)
            {
	    TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
	    exit (-1);
            }
          dump_info(dump.infile, dump.format, "Reading image","%d from %s", 
                    dump_images, TIFFFileName(in));
          } 
        length = strlen(dump.outfilename);
        if (length > 0)
          {
          if (dump.outfile != NULL)
            fclose (dump.outfile);

          /* dump.outfilename is guaranteed to be NUL termimated and have 20 bytes 
             fewer than PATH_MAX */ 
          snprintf(temp_filename, sizeof(temp_filename), "%s-write-%03d.%s",
		   dump.outfilename, dump_images,
                  (dump.format == DUMP_TEXT) ? "txt" : "raw");
          if ((dump.outfile = fopen(temp_filename, dump.mode)) == NULL)
            {
	      TIFFError ("Unable to open dump file for writing", "%s", temp_filename);
	    exit (-1);
            }
          dump_info(dump.outfile, dump.format, "Writing image","%d from %s", 
                    dump_images, TIFFFileName(in));
          } 
        }

      if (dump.debug)
         TIFFError("main", "Reading image %4d of %4d total pages.", dirnum + 1, total_pages);

      if (loadImage(in, &image, &dump, &read_buff))
        {
        TIFFError("main", "Unable to load source image");
        exit (-1);
        }

      /* Correct the image orientation if it was not ORIENTATION_TOPLEFT.
       */
      if (image.adjustments != 0)
        {
	if (correct_orientation(&image, &read_buff))
	    TIFFError("main", "Unable to correct image orientation");
        }

      if (getCropOffsets(&image, &crop, &dump))
        {
        TIFFError("main", "Unable to define crop regions");
        exit (-1);
	}

      if (crop.selections > 0)
        {
        if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
          {
          TIFFError("main", "Unable to process image selections");
          exit (-1);
	  }
	}
      else  /* Single image segment without zones or regions */
        {
        if (createCroppedImage(&image, &crop, &read_buff, &crop_buff))
          {
          TIFFError("main", "Unable to create output image");
          exit (-1);
	  }
	}
      if (page.mode == PAGE_MODE_NONE)
        {  /* Whole image or sections not based on output page size */
        if (crop.selections > 0)
          {
	  writeSelections(in, &out, &crop, &image, &dump, seg_buffs,
                          mp, argv[argc - 1], &next_page, total_pages);
          }
	else  /* One file all images and sections */
          {
	  if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1],
                                  &next_page))
             exit (1);
          if (writeCroppedImage(in, out, &image, &dump,crop.combined_width, 
                                crop.combined_length, crop_buff, next_page, total_pages))
            {
             TIFFError("main", "Unable to write new image");
             exit (-1);
	    }
          }
	}
      else
        {
	/* If we used a crop buffer, our data is there, otherwise it is
         * in the read_buffer
         */
	if (crop_buff != NULL)  
	  sect_src = crop_buff;
        else
          sect_src = read_buff;
        /* Break input image into pages or rows and columns */
        if (computeOutputPixelOffsets(&crop, &image, &page, sections, &dump))
          {
          TIFFError("main", "Unable to compute output section data");
          exit (-1);
	  }
        /* If there are multiple files on the command line, the final one is assumed 
         * to be the output filename into which the images are written.
         */
	if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page))
          exit (1);

	if (writeImageSections(in, out, &image, &page, sections, &dump, sect_src, &sect_buff))
          {
          TIFFError("main", "Unable to write image sections");
          exit (-1);
	  }
        }

      /* No image list specified, just read the next image */
      if (image_count == 0)
        dirnum++;
      else
        {
	dirnum = (tdir_t)(imagelist[next_image] - 1);
        next_image++;
        }

      if (dirnum == MAX_IMAGES - 1)
        dirnum = TIFFNumberOfDirectories(in) - 1;

      if (!TIFFSetDirectory(in, (tdir_t)dirnum))
        end_of_input = TRUE;
      }
    TIFFClose(in);
    optind++;
    }

  /* If we did not use the read buffer as the crop buffer */
  if (read_buff)
    _TIFFfree(read_buff);

  if (crop_buff)
    _TIFFfree(crop_buff);

  if (sect_buff)
    _TIFFfree(sect_buff);

   /* Clean up any segment buffers used for zones or regions */
  for (seg = 0; seg < crop.selections; seg++)
    _TIFFfree (seg_buffs[seg].buffer);

  if (dump.format != DUMP_NONE)
    {
    if (dump.infile != NULL)
     fclose (dump.infile);

    if (dump.outfile != NULL)
      {
      dump_info (dump.outfile, dump.format, "", "Completed run for %s", TIFFFileName(out));
      fclose (dump.outfile);
      }
    }

  TIFFClose(out);

  return (0);
  } /* end main */

Project: libtiff

mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, unsigned char *ibuff)
  {
  int      shift_width;
  uint32   bytes_per_pixel, bytes_per_sample;
  uint32   row, rowsize, row_offset;
  unsigned char *line_buff = NULL;
  unsigned char *src;
  unsigned char *dst;

  src = ibuff;
  rowsize = ((width * bps * spp) + 7) / 8;
  switch (mirror)
    {
    case MIRROR_BOTH:
    case MIRROR_VERT: 
             line_buff = (unsigned char *)_TIFFmalloc(rowsize);
             if (line_buff == NULL)
               {
	       TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize);
               return (-1);
               }

             dst = ibuff + (rowsize * (length - 1));
             for (row = 0; row < length / 2; row++)
               {
	      _TIFFmemcpy(line_buff, src, rowsize);
	      _TIFFmemcpy(src, dst,  rowsize);
	      _TIFFmemcpy(dst, line_buff, rowsize);
               src += (rowsize);
               dst -= (rowsize);                                 
               }
             if (line_buff)
               _TIFFfree(line_buff);
             if (mirror == MIRROR_VERT)
               break;
    case MIRROR_HORIZ :
              if ((bps % 8) == 0) /* byte alligned data */
                { 
                for (row = 0; row < length; row++)
                  {
		  row_offset = row * rowsize;
                  src = ibuff + row_offset;
                  dst = ibuff + row_offset + rowsize;
                  if (reverseSamplesBytes(spp, bps, width, src, dst))
                    {
		    return (-1);
                    }
		  }
		}
	      else
                { /* non 8 bit per sample  data */
                if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1)))
                  {
                  TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
                  return (-1);
                  }
                bytes_per_sample = (bps + 7) / 8;
                bytes_per_pixel  = ((bps * spp) + 7) / 8;
                if (bytes_per_pixel < (bytes_per_sample + 1))
                  shift_width = bytes_per_pixel;
                else
                  shift_width = bytes_per_sample + 1;

                for (row = 0; row < length; row++)
                  {
		  row_offset = row * rowsize;
                  src = ibuff + row_offset;
                  _TIFFmemset (line_buff, '\0', rowsize);
                  switch (shift_width)
                    {
                    case 1: if (reverseSamples16bits(spp, bps, width, src, line_buff))
                              {
		              _TIFFfree(line_buff);
                              return (-1);
                              }
                             _TIFFmemcpy (src, line_buff, rowsize);
                             break;
                    case 2: if (reverseSamples24bits(spp, bps, width, src, line_buff))
                              {
		              _TIFFfree(line_buff);
                              return (-1);
                              }
                             _TIFFmemcpy (src, line_buff, rowsize);
                             break;
                    case 3: 
                    case 4: 
                    case 5: if (reverseSamples32bits(spp, bps, width, src, line_buff))
                              {
		              _TIFFfree(line_buff);
                              return (-1);
                              }
                             _TIFFmemcpy (src, line_buff, rowsize);
                             break;
                    default: TIFFError("mirrorImage","Unsupported bit depth %d", bps);
		             _TIFFfree(line_buff);
                             return (-1);      
                    }
		  }
                if (line_buff)
                  _TIFFfree(line_buff);
		}
             break;

    default: TIFFError ("mirrorImage", "Invalid mirror axis %d", mirror);
             return (-1);
             break;
    }

  return (0);
  }

Project: libtiff

processCompressOptions(char* opt)
  {
  char* cp = NULL;

  if (strneq(opt, "none",4))
    {
    defcompression = COMPRESSION_NONE;
    }
  else if (streq(opt, "packbits"))
    {
    defcompression = COMPRESSION_PACKBITS;
    }
  else if (strneq(opt, "jpeg", 4))
    {
    cp = strchr(opt, ':');
    defcompression = COMPRESSION_JPEG;

    while (cp)
      {
      if (isdigit((int)cp[1]))
	quality = atoi(cp + 1);
      else if (strneq(cp + 1, "raw", 3 ))
	jpegcolormode = JPEGCOLORMODE_RAW;
      else if (strneq(cp + 1, "rgb", 3 ))
	jpegcolormode = JPEGCOLORMODE_RGB;
      else
	usage();
      cp = strchr(cp + 1, ':');
      }
    }
  else if (strneq(opt, "g3", 2))
    {
    processG3Options(opt);
    defcompression = COMPRESSION_CCITTFAX3;
    }
  else if (streq(opt, "g4"))
    {
    defcompression = COMPRESSION_CCITTFAX4;
    }
  else if (strneq(opt, "lzw", 3))
    {
    cp = strchr(opt, ':');
    if (cp)
      defpredictor = atoi(cp+1);
    defcompression = COMPRESSION_LZW;
    }
  else if (strneq(opt, "zip", 3))
    {
    cp = strchr(opt, ':');
    if (cp)
      defpredictor = atoi(cp+1);
    defcompression = COMPRESSION_ADOBE_DEFLATE;
   }
  else
    return (0);

  return (1);
  }

Project: libtiff

processCropSelections(struct image_data *image, struct crop_mask *crop, 
                      unsigned char **read_buff_ptr, struct buffinfo seg_buffs[])
  {
  int       i;
  uint32    width, length, total_width, total_length;
  tsize_t   cropsize;
  unsigned  char *crop_buff = NULL;
  unsigned  char *read_buff = NULL;
  unsigned  char *next_buff = NULL;
  tsize_t   prev_cropsize = 0;

  read_buff = *read_buff_ptr;

  if (crop->img_mode == COMPOSITE_IMAGES)
    {
    cropsize = crop->bufftotal;
    crop_buff = seg_buffs[0].buffer; 
    if (!crop_buff)
      crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
    else
      {
      prev_cropsize = seg_buffs[0].size;
      if (prev_cropsize < cropsize)
        {
        next_buff = _TIFFrealloc(crop_buff, cropsize);
        if (! next_buff)
          {
          _TIFFfree (crop_buff);
          crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
          }
        else
          crop_buff = next_buff;
        }
      }

    if (!crop_buff)
      {
      TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
      return (-1);
      }
 
    _TIFFmemset(crop_buff, 0, cropsize);
    seg_buffs[0].buffer = crop_buff;
    seg_buffs[0].size = cropsize;

    /* Checks for matching width or length as required */
    if (extractCompositeRegions(image, crop, read_buff, crop_buff) != 0)
      return (1);

    if (crop->crop_mode & CROP_INVERT)
      {
      switch (crop->photometric)
        {
        /* Just change the interpretation */
        case PHOTOMETRIC_MINISWHITE:
        case PHOTOMETRIC_MINISBLACK:
	     image->photometric = crop->photometric;
	     break;
        case INVERT_DATA_ONLY:
        case INVERT_DATA_AND_TAG:
             if (invertImage(image->photometric, image->spp, image->bps, 
                             crop->combined_width, crop->combined_length, crop_buff))
               {
               TIFFError("processCropSelections", 
                         "Failed to invert colorspace for composite regions");
               return (-1);
               }
             if (crop->photometric == INVERT_DATA_AND_TAG)
               {
               switch (image->photometric)
                 {
                 case PHOTOMETRIC_MINISWHITE:
 	              image->photometric = PHOTOMETRIC_MINISBLACK;
	              break;
                 case PHOTOMETRIC_MINISBLACK:
 	              image->photometric = PHOTOMETRIC_MINISWHITE;
	              break;
                 default:
	              break;
	         }
	       }
             break;
        default: break;
        }
      }

    /* Mirror and Rotate will not work with multiple regions unless they are the same width */
    if (crop->crop_mode & CROP_MIRROR)
      {
      if (mirrorImage(image->spp, image->bps, crop->mirror, 
                      crop->combined_width, crop->combined_length, crop_buff))
        {
        TIFFError("processCropSelections", "Failed to mirror composite regions %s", 
	         (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
        return (-1);
        }
      }

    if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
      {
      if (rotateImage(crop->rotation, image, &crop->combined_width, 
                      &crop->combined_length, &crop_buff))
        {
        TIFFError("processCropSelections", 
                  "Failed to rotate composite regions by %d degrees", crop->rotation);
        return (-1);
        }
      seg_buffs[0].buffer = crop_buff;
      seg_buffs[0].size = (((crop->combined_width * image->bps + 7 ) / 8)
                            * image->spp) * crop->combined_length; 
      }
    }
  else  /* Separated Images */
    {
    total_width = total_length = 0;
    for (i = 0; i < crop->selections; i++)
      {
      cropsize = crop->bufftotal;
      crop_buff = seg_buffs[i].buffer; 
      if (!crop_buff)
        crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
      else
        {
        prev_cropsize = seg_buffs[0].size;
        if (prev_cropsize < cropsize)
          {
          next_buff = _TIFFrealloc(crop_buff, cropsize);
          if (! next_buff)
            {
            _TIFFfree (crop_buff);
            crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
            }
          else
            crop_buff = next_buff;
          }
        }

      if (!crop_buff)
        {
        TIFFError("processCropSelections", "Unable to allocate/reallocate crop buffer");
        return (-1);
        }
 
      _TIFFmemset(crop_buff, 0, cropsize);
      seg_buffs[i].buffer = crop_buff;
      seg_buffs[i].size = cropsize;

      if (extractSeparateRegion(image, crop, read_buff, crop_buff, i))
        {
	TIFFError("processCropSelections", "Unable to extract cropped region %d from image", i);
        return (-1);
        }
    
      width  = crop->regionlist[i].width;
      length = crop->regionlist[i].length;

      if (crop->crop_mode & CROP_INVERT)
        {
        switch (crop->photometric)
          {
          /* Just change the interpretation */
          case PHOTOMETRIC_MINISWHITE:
          case PHOTOMETRIC_MINISBLACK:
	       image->photometric = crop->photometric;
	       break;
          case INVERT_DATA_ONLY:
          case INVERT_DATA_AND_TAG:
               if (invertImage(image->photometric, image->spp, image->bps, 
                               width, length, crop_buff))
                 {
                 TIFFError("processCropSelections", 
                           "Failed to invert colorspace for region");
                 return (-1);
                 }
               if (crop->photometric == INVERT_DATA_AND_TAG)
                 {
                 switch (image->photometric)
                   {
                   case PHOTOMETRIC_MINISWHITE:
 	                image->photometric = PHOTOMETRIC_MINISBLACK;
	                break;
                   case PHOTOMETRIC_MINISBLACK:
 	                image->photometric = PHOTOMETRIC_MINISWHITE;
	                break;
                   default:
	                break;
	           }
	         }
               break;
          default: break;
          }
        }

      if (crop->crop_mode & CROP_MIRROR)
        {
        if (mirrorImage(image->spp, image->bps, crop->mirror, 
                        width, length, crop_buff))
          {
          TIFFError("processCropSelections", "Failed to mirror crop region %s", 
	           (crop->rotation == MIRROR_HORIZ) ? "horizontally" : "vertically");
          return (-1);
          }
        }

      if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
        {
	if (rotateImage(crop->rotation, image, &crop->regionlist[i].width, 
			&crop->regionlist[i].length, &crop_buff))
          {
          TIFFError("processCropSelections", 
                    "Failed to rotate crop region by %d degrees", crop->rotation);
          return (-1);
          }
        total_width  += crop->regionlist[i].width;
        total_length += crop->regionlist[i].length;
        crop->combined_width = total_width;
        crop->combined_length = total_length;
        seg_buffs[i].buffer = crop_buff;
        seg_buffs[i].size = (((crop->regionlist[i].width * image->bps + 7 ) / 8)
                               * image->spp) * crop->regionlist[i].length; 
        }
      }
    }
  return (0);
  } /* end processCropSelections */

Project: libtiff

void  process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 *dirnum,
	                    uint16 *defconfig, uint16 *deffillorder, uint32 *deftilewidth,
                            uint32 *deftilelength, uint32 *defrowsperstrip,
		            struct crop_mask *crop_data, struct pagedef *page, 
                            struct dump_opts *dump,
                            unsigned int     *imagelist, unsigned int   *image_count )
    {
    int   c, good_args = 0;
    char *opt_offset   = NULL;    /* Position in string of value sought */
    char *opt_ptr      = NULL;    /* Pointer to next token in option set */
    char *sep          = NULL;    /* Pointer to a token separator */
    unsigned int  i, j, start, end;
#if !HAVE_DECL_OPTARG
    extern int   optind;
    extern char* optarg;
#endif

    *mp++ = 'w';
    *mp = '\0';
    while ((c = getopt(argc, argv,
       "ac:d:e:f:hil:m:p:r:stvw:z:BCD:E:F:H:I:J:K:LMN:O:P:R:S:U:V:X:Y:Z:")) != -1)
      {
    good_args++;
    switch (c) {
      case 'a': mode[0] = 'a';	/* append to output */
		break;
      case 'c':	if (!processCompressOptions(optarg)) /* compression scheme */
		  {
		  TIFFError ("Unknown compression option", "%s", optarg);
                  TIFFError ("For valid options type", "tiffcrop -h");
                  exit (-1);
                  }
		break;
      case 'd':	start = strtoul(optarg, NULL, 0); /* initial IFD offset */
	        if (start == 0)
                  {
		  TIFFError ("","Directory offset must be greater than zero");
		  TIFFError ("For valid options type", "tiffcrop -h");
                  exit (-1);
		  }
	        *dirnum = start - 1;
		break;
      case 'e': switch (tolower((int) optarg[0])) /* image export modes*/
                  {
		  case 'c': crop_data->exp_mode = ONE_FILE_COMPOSITE;
 		            crop_data->img_mode = COMPOSITE_IMAGES;
		            break; /* Composite */
		  case 'd': crop_data->exp_mode = ONE_FILE_SEPARATED;
 		            crop_data->img_mode = SEPARATED_IMAGES;
		            break; /* Divided */
		  case 'i': crop_data->exp_mode = FILE_PER_IMAGE_COMPOSITE;
 		            crop_data->img_mode = COMPOSITE_IMAGES;
		            break; /* Image */
		  case 'm': crop_data->exp_mode = FILE_PER_IMAGE_SEPARATED;
 		            crop_data->img_mode = SEPARATED_IMAGES;
		            break; /* Multiple */
		  case 's': crop_data->exp_mode = FILE_PER_SELECTION;
 		            crop_data->img_mode = SEPARATED_IMAGES;
		            break; /* Sections */
		  default:  TIFFError ("Unknown export mode","%s", optarg);
                            TIFFError ("For valid options type", "tiffcrop -h");
                            exit (-1);
                  }
	        break;
      case 'f':	if (streq(optarg, "lsb2msb"))	   /* fill order */
		  *deffillorder = FILLORDER_LSB2MSB;
		else if (streq(optarg, "msb2lsb"))
		  *deffillorder = FILLORDER_MSB2LSB;
		else
		  {
		  TIFFError ("Unknown fill order", "%s", optarg);
                  TIFFError ("For valid options type", "tiffcrop -h");
                  exit (-1);
                  }
		break;
      case 'h':	usage();
		break;
      case 'i':	ignore = TRUE;		/* ignore errors */
		break;
      case 'l':	outtiled = TRUE;	 /* tile length */
		*deftilelength = atoi(optarg);
		break;
      case 'p': /* planar configuration */
		if (streq(optarg, "separate"))
		  *defconfig = PLANARCONFIG_SEPARATE;
		else if (streq(optarg, "contig"))
		  *defconfig = PLANARCONFIG_CONTIG;
		else
		  {
		  TIFFError ("Unkown planar configuration", "%s", optarg);
                  TIFFError ("For valid options type", "tiffcrop -h");
                  exit (-1);
                  }
		break;
      case 'r':	/* rows/strip */
		*defrowsperstrip = atol(optarg);
		break;
      case 's':	/* generate stripped output */
		outtiled = FALSE;
		break;
      case 't':	/* generate tiled output */
		outtiled = TRUE;
		break;
      case 'v': TIFFError("Library Release", "%s", TIFFGetVersion());
                TIFFError ("Tiffcrop version", "%s, last updated: %s", 
			   tiffcrop_version_id, tiffcrop_rev_date);
 	        TIFFError ("Tiffcp code", "Copyright (c) 1988-1997 Sam Leffler");
		TIFFError ("           ", "Copyright (c) 1991-1997 Silicon Graphics, Inc");
                TIFFError ("Tiffcrop additions", "Copyright (c) 2007-2010 Richard Nolde");
	        exit (0);
		break;
      case 'w':	/* tile width */
		outtiled = TRUE;
		*deftilewidth = atoi(optarg);
		break;
      case 'z': /* regions of an image specified as x1,y1,x2,y2:x3,y3,x4,y4 etc */
	        crop_data->crop_mode |= CROP_REGIONS;
		for (i = 0, opt_ptr = strtok (optarg, ":");
                   ((opt_ptr != NULL) &&  (i < MAX_REGIONS));
                    (opt_ptr = strtok (NULL, ":")), i++)
                    {
		    crop_data->regions++;
                    if (sscanf(opt_ptr, "%lf,%lf,%lf,%lf",
			       &crop_data->corners[i].X1, &crop_data->corners[i].Y1,
			       &crop_data->corners[i].X2, &crop_data->corners[i].Y2) != 4)
                      {
                      TIFFError ("Unable to parse coordinates for region", "%d %s", i, optarg);
		      TIFFError ("For valid options type", "tiffcrop -h");
                      exit (-1);
		      }
                    }
                /*  check for remaining elements over MAX_REGIONS */
                if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
                  {
		  TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS, optarg);
		  TIFFError ("For valid options type", "tiffcrop -h");
                  exit (-1);;
                  }
		break;
      /* options for file open modes */
      case 'B': *mp++ = 'b'; *mp = '\0';
		break;
      case 'L': *mp++ = 'l'; *mp = '\0';
		break;
      case 'M': *mp++ = 'm'; *mp = '\0';
		break;
      case 'C': *mp++ = 'c'; *mp = '\0';
		break;
      /* options for Debugging / data dump */
      case 'D': for (i = 0, opt_ptr = strtok (optarg, ",");
                    (opt_ptr != NULL);
                    (opt_ptr = strtok (NULL, ",")), i++)
                    {
		    opt_offset = strpbrk(opt_ptr, ":=");
                    if (opt_offset == NULL)
                      {
                      TIFFError("Invalid dump option", "%s", optarg);
                      TIFFError ("For valid options type", "tiffcrop -h");
                      exit (-1);
		      }
                      
                    *opt_offset = '\0';
                    /* convert option to lowercase */
                    end = strlen (opt_ptr);
                    for (i = 0; i < end; i++)
                      *(opt_ptr + i) = tolower((int) *(opt_ptr + i));
                    /* Look for dump format specification */
                    if (strncmp(opt_ptr, "for", 3) == 0)
                      {
		      /* convert value to lowercase */
                      end = strlen (opt_offset + 1);
                      for (i = 1; i <= end; i++)
                        *(opt_offset + i) = tolower((int) *(opt_offset + i));
                      /* check dump format value */
		      if (strncmp (opt_offset + 1, "txt", 3) == 0)
                        {
                        dump->format = DUMP_TEXT;
                        strcpy (dump->mode, "w");
                        }
                      else
                        {
		        if (strncmp(opt_offset + 1, "raw", 3) == 0)
                          {
                          dump->format = DUMP_RAW;
                          strcpy (dump->mode, "wb");
                          }
                        else
                          {
                          TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset + 1);
                          TIFFError ("For valid options type", "tiffcrop -h");
                          exit (-1);
		          }
			}
                      }
		    else
                      { /* Look for dump level specification */
                      if (strncmp (opt_ptr, "lev", 3) == 0)
                        dump->level = atoi(opt_offset + 1);
                        /* Look for input data dump file name */
                      if (strncmp (opt_ptr, "in", 2) == 0)
		        {
                        strncpy (dump->infilename, opt_offset + 1, PATH_MAX - 20);
                        dump->infilename[PATH_MAX - 20] = '\0';
                        }
                        /* Look for output data dump file name */
                      if (strncmp (opt_ptr, "out", 3) == 0)
			{
                        strncpy (dump->outfilename, opt_offset + 1, PATH_MAX - 20);
                        dump->outfilename[PATH_MAX - 20] = '\0';
                        }
                      if (strncmp (opt_ptr, "deb", 3) == 0)
			dump->debug = atoi(opt_offset + 1);
		      }
                    }
	        if ((strlen(dump->infilename)) || (strlen(dump->outfilename)))
                  {
		  if (dump->level == 1)
                    TIFFError("","Defaulting to dump level 1, no data.");
	          if (dump->format == DUMP_NONE)
                    {
		    TIFFError("", "You must specify a dump format for dump files");
		    TIFFError ("For valid options type", "tiffcrop -h");
		    exit (-1);
		    }
                  }
	        break;

      /* image manipulation routine options */
      case 'm': /* margins to exclude from selection, uppercase M was already used */
		/* order of values must be TOP, LEFT, BOTTOM, RIGHT */
		crop_data->crop_mode |= CROP_MARGINS;
                for (i = 0, opt_ptr = strtok (optarg, ",:");
                    ((opt_ptr != NULL) &&  (i < 4));
                     (opt_ptr = strtok (NULL, ",:")), i++)
                    {
		    crop_data->margins[i] = atof(opt_ptr);
                    }
		break;
      case 'E':	/* edge reference */
		switch (tolower((int) optarg[0]))
                  {
		  case 't': crop_data->edge_ref = EDGE_TOP;
                            break;
                  case 'b': crop_data->edge_ref = EDGE_BOTTOM;
                             break;
                  case 'l': crop_data->edge_ref = EDGE_LEFT;
                            break;
                  case 'r': crop_data->edge_ref = EDGE_RIGHT;
                            break;
		  default:  TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg);
			    TIFFError ("For valid options type", "tiffcrop -h");
                            exit (-1);
		  }
		break;
      case 'F': /* flip eg mirror image or cropped segment, M was already used */
		crop_data->crop_mode |= CROP_MIRROR;
		switch (tolower((int) optarg[0]))
                  {
		  case  'h': crop_data->mirror = MIRROR_HORIZ;
                             break;
                  case  'v': crop_data->mirror = MIRROR_VERT;
                             break;
                  case  'b': crop_data->mirror = MIRROR_BOTH;
                             break;
		  default:   TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg);
			     TIFFError ("For valid options type", "tiffcrop -h");
                             exit (-1);
		  }
		break;
      case 'H': /* set horizontal resolution to new value */
		page->hres = atof (optarg);
                page->mode |= PAGE_MODE_RESOLUTION;
		break;
      case 'I': /* invert the color space, eg black to white */
		crop_data->crop_mode |= CROP_INVERT;
                /* The PHOTOMETIC_INTERPRETATION tag may be updated */
                if (streq(optarg, "black"))
                  {
		  crop_data->photometric = PHOTOMETRIC_MINISBLACK;
		  continue;
                  }
                if (streq(optarg, "white"))
                  {
		  crop_data->photometric = PHOTOMETRIC_MINISWHITE;
                  continue;
                  }
                if (streq(optarg, "data")) 
                  {
		  crop_data->photometric = INVERT_DATA_ONLY;
                  continue;
                  }
                if (streq(optarg, "both"))
                  {
		  crop_data->photometric = INVERT_DATA_AND_TAG;
                  continue;
                  }

		TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg);
		TIFFError ("For valid options type", "tiffcrop -h");
                exit (-1);
		break;
      case 'J': /* horizontal margin for sectioned ouput pages */ 
		page->hmargin = atof(optarg);
                page->mode |= PAGE_MODE_MARGINS;
		break;
      case 'K': /* vertical margin for sectioned ouput pages*/ 
                page->vmargin = atof(optarg);
                page->mode |= PAGE_MODE_MARGINS;
		break;
      case 'N':	/* list of images to process */
                for (i = 0, opt_ptr = strtok (optarg, ",");
                    ((opt_ptr != NULL) &&  (i < MAX_IMAGES));
                     (opt_ptr = strtok (NULL, ",")))
                     { /* We do not know how many images are in file yet 
			* so we build a list to include the maximum allowed
                        * and follow it until we hit the end of the file.
                        * Image count is not accurate for odd, even, last
                        * so page numbers won't be valid either.
                        */
		     if (streq(opt_ptr, "odd"))
                       {
		       for (j = 1; j <= MAX_IMAGES; j += 2)
			 imagelist[i++] = j;
                       *image_count = (MAX_IMAGES - 1) / 2;
                       break;
		       }
		     else
                       {
		       if (streq(opt_ptr, "even"))
                         {
			 for (j = 2; j <= MAX_IMAGES; j += 2)
			   imagelist[i++] = j;
                         *image_count = MAX_IMAGES / 2;
                         break;
			 }
		       else
                         {
			 if (streq(opt_ptr, "last"))
			   imagelist[i++] = MAX_IMAGES;
			 else  /* single value between commas */
			   {
			   sep = strpbrk(opt_ptr, ":-");
			   if (!sep)
			     imagelist[i++] = atoi(opt_ptr);
                           else
                             {
			     *sep = '\0';
                             start = atoi (opt_ptr);
                             if (!strcmp((sep + 1), "last"))
			       end = MAX_IMAGES;
                             else
                               end = atoi (sep + 1);
                             for (j = start; j <= end && j - start + i < MAX_IMAGES; j++)
			       imagelist[i++] = j;
			     }
			   }
			 }
		      }
		    }
                *image_count = i;
		break;
      case 'O': /* page orientation */ 
		switch (tolower((int) optarg[0]))
                  {
		  case  'a': page->orient = ORIENTATION_AUTO;
                             break;
		  case  'p': page->orient = ORIENTATION_PORTRAIT;
                             break;
		  case  'l': page->orient = ORIENTATION_LANDSCAPE;
                             break;
		  default:  TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg);
			    TIFFError ("For valid options type", "tiffcrop -h");
                            exit (-1);
		  }
		break;
      case 'P': /* page size selection */ 
	        if (sscanf(optarg, "%lfx%lf", &page->width, &page->length) == 2)
                  {
                  strcpy (page->name, "Custom"); 
                  page->mode |= PAGE_MODE_PAPERSIZE;
                  break;
                  }
                if (get_page_geometry (optarg, page))
                  {
		  if (!strcmp(optarg, "list"))
                    {
		    TIFFError("", "Name            Width   Length (in inches)");
                    for (i = 0; i < MAX_PAPERNAMES - 1; i++)
                      TIFFError ("", "%-15.15s %5.2f   %5.2f", 
			       PaperTable[i].name, PaperTable[i].width, 
                               PaperTable[i].length);
		    exit (-1);                   
                    }
     
		  TIFFError ("Invalid paper size", "%s", optarg);
                  TIFFError ("", "Select one of:");
		  TIFFError("", "Name            Width   Length (in inches)");
                  for (i = 0; i < MAX_PAPERNAMES - 1; i++)
                    TIFFError ("", "%-15.15s %5.2f   %5.2f", 
			       PaperTable[i].name, PaperTable[i].width, 
                               PaperTable[i].length);
		  exit (-1);
		  }
		else
                  {
                  page->mode |= PAGE_MODE_PAPERSIZE;
		  }
		break;
      case 'R': /* rotate image or cropped segment */
		crop_data->crop_mode |= CROP_ROTATE;
		switch (strtoul(optarg, NULL, 0))
                  {
		  case  90:  crop_data->rotation = (uint16)90;
                             break;
                  case  180: crop_data->rotation = (uint16)180;
                             break;
                  case  270: crop_data->rotation = (uint16)270;
                             break;
		  default:   TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg);
			     TIFFError ("For valid options type", "tiffcrop -h");
                             exit (-1);
		  }
		break;
      case 'S':	/* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */
		sep = strpbrk(optarg, ",:");
		if (sep)
                  {
                  *sep = '\0';
                  page->cols = atoi(optarg);
                  page->rows = atoi(sep +1);
		  }
                else
                  {
                  page->cols = atoi(optarg);
                  page->rows = atoi(optarg);
		  }
                if ((page->cols * page->rows) > MAX_SECTIONS)
                  {
		  TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS);
		  exit (-1);
                  }
                page->mode |= PAGE_MODE_ROWSCOLS;
		break;
      case 'U':	/* units for measurements and offsets */
		if (streq(optarg, "in"))
                  {
		  crop_data->res_unit = RESUNIT_INCH;
		  page->res_unit = RESUNIT_INCH;
		  }
		else if (streq(optarg, "cm"))
		  {
		  crop_data->res_unit = RESUNIT_CENTIMETER;
		  page->res_unit = RESUNIT_CENTIMETER;
		  }
		else if (streq(optarg, "px"))
		  {
		  crop_data->res_unit = RESUNIT_NONE;
		  page->res_unit = RESUNIT_NONE;
		  }
		else
                  {
		  TIFFError ("Illegal unit of measure","%s", optarg);
		  TIFFError ("For valid options type", "tiffcrop -h");
                  exit (-1);
		  }
		break;
      case 'V': /* set vertical resolution to new value */
		page->vres = atof (optarg);
                page->mode |= PAGE_MODE_RESOLUTION;
		break;
      case 'X':	/* selection width */
		crop_data->crop_mode |= CROP_WIDTH;
		crop_data->width = atof(optarg);
		break;
      case 'Y':	/* selection length */
		crop_data->crop_mode |= CROP_LENGTH;
		crop_data->length = atof(optarg);
		break;
      case 'Z': /* zones of an image X:Y read as zone X of Y */
		crop_data->crop_mode |= CROP_ZONES;
		for (i = 0, opt_ptr = strtok (optarg, ",");
                   ((opt_ptr != NULL) &&  (i < MAX_REGIONS));
                    (opt_ptr = strtok (NULL, ",")), i++)
                    {
		    crop_data->zones++;
		    opt_offset = strchr(opt_ptr, ':');
		    if (!opt_offset) {
			TIFFError("Wrong parameter syntax for -Z", "tiffcrop -h");
			exit(-1);
		    }
                    *opt_offset = '\0';
                    crop_data->zonelist[i].position = atoi(opt_ptr);
                    crop_data->zonelist[i].total    = atoi(opt_offset + 1);
                    }
                /*  check for remaining elements over MAX_REGIONS */
                if ((opt_ptr != NULL) && (i >= MAX_REGIONS))
                  {
		  TIFFError("Zone list exceeds region limit", "%d",  MAX_REGIONS);
		  exit (-1);
                  }
		break;
    case '?':	TIFFError ("For valid options type", "tiffcrop -h");
                exit (-1);
		/*NOTREACHED*/
      }
    }
  }  /* end process_command_opts */

Project: libtiff

static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, 
                                         uint32 width, uint16 spp,
                                         struct dump_opts *dump)
  {
  int i, bytes_per_sample, bytes_per_pixel, shift_width, result = 1;
  uint32 j;
  int32  bytes_read = 0;
  uint16 bps, planar;
  uint32 nstrips;
  uint32 strips_per_sample;
  uint32 src_rowsize, dst_rowsize, rows_processed, rps;
  uint32 rows_this_strip = 0;
  tsample_t s;
  tstrip_t  strip;
  tsize_t scanlinesize = TIFFScanlineSize(in);
  tsize_t stripsize    = TIFFStripSize(in);
  unsigned char *srcbuffs[MAX_SAMPLES];
  unsigned char *buff = NULL;
  unsigned char *dst = NULL;

  if (obuf == NULL)
    {
    TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
    return (0);
    }

  memset (srcbuffs, '\0', sizeof(srcbuffs));
  TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
  TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
  TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
  if (rps > length)
    rps = length;

  bytes_per_sample = (bps + 7) / 8; 
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
  if (bytes_per_pixel < (bytes_per_sample + 1))
    shift_width = bytes_per_pixel;
  else
    shift_width = bytes_per_sample + 1;

  src_rowsize = ((bps * width) + 7) / 8;
  dst_rowsize = ((bps * width * spp) + 7) / 8;
  dst = obuf;

  if ((dump->infile != NULL) && (dump->level == 3))
    {
    dump_info  (dump->infile, dump->format, "", 
                "Image width %d, length %d, Scanline size, %4d bytes",
                width, length,  scanlinesize);
    dump_info  (dump->infile, dump->format, "", 
                "Bits per sample %d, Samples per pixel %d, Shift width %d",
		bps, spp, shift_width);
    }

  /* Libtiff seems to assume/require that data for separate planes are 
   * written one complete plane after another and not interleaved in any way.
   * Multiple scanlines and possibly strips of the same plane must be 
   * written before data for any other plane.
   */
  nstrips = TIFFNumberOfStrips(in);
  strips_per_sample = nstrips /spp;

  for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
    {
    srcbuffs[s] = NULL;
    buff = _TIFFmalloc(stripsize);
    if (!buff)
      {
      TIFFError ("readSeparateStripsIntoBuffer", 
                 "Unable to allocate strip read buffer for sample %d", s);
      for (i = 0; i < s; i++)
        _TIFFfree (srcbuffs[i]);
      return 0;
      }
    srcbuffs[s] = buff;
    }

  rows_processed = 0;
  for (j = 0; (j < strips_per_sample) && (result == 1); j++)
    {
    for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
      {
      buff = srcbuffs[s];
      strip = (s * strips_per_sample) + j; 
      bytes_read = TIFFReadEncodedStrip (in, strip, buff, stripsize);
      rows_this_strip = bytes_read / src_rowsize;
      if (bytes_read < 0 && !ignore)
        {
        TIFFError(TIFFFileName(in),
	          "Error, can't read strip %lu for sample %d",
         	   (unsigned long) strip, s + 1);
        result = 0;
        break;
        }
#ifdef DEVELMODE
      TIFFError("", "Strip %2d, read %5d bytes for %4d scanlines, shift width %d", 
		strip, bytes_read, rows_this_strip, shift_width);
#endif
      }

    if (rps > rows_this_strip)
      rps = rows_this_strip;
    dst = obuf + (dst_rowsize * rows_processed);
    if ((bps % 8) == 0)
      {
      if (combineSeparateSamplesBytes (srcbuffs, dst, width, rps,
                                       spp, bps, dump->infile, 
                                       dump->format, dump->level))
        {
        result = 0;
        break;
	}
      }
    else
      {
      switch (shift_width)
        {
        case 1: if (combineSeparateSamples8bits (srcbuffs, dst, width, rps,
                                                 spp, bps, dump->infile,
                                                 dump->format, dump->level))
	          {
                  result = 0;
                  break;
      	          }
	        break;
        case 2: if (combineSeparateSamples16bits (srcbuffs, dst, width, rps,
                                                  spp, bps, dump->infile,
                                                  dump->format, dump->level))
	          {
                  result = 0;
                  break;
		  }
	        break;
        case 3: if (combineSeparateSamples24bits (srcbuffs, dst, width, rps,
                                                  spp, bps, dump->infile,
                                                  dump->format, dump->level))
	          {
                  result = 0;
                  break;
       	          }
                break;
        case 4: 
        case 5:
        case 6:
        case 7:
        case 8: if (combineSeparateSamples32bits (srcbuffs, dst, width, rps,
                                                  spp, bps, dump->infile,
                                                  dump->format, dump->level))
	          {
                  result = 0;
                  break;
		  }
	        break;
        default: TIFFError ("readSeparateStripsIntoBuffer", "Unsupported bit depth: %d", bps);
                  result = 0;
                  break;
        }
      }
 
    if ((rows_processed + rps) > length)
      {
      rows_processed = length;
      rps = length - rows_processed;
      }
    else
      rows_processed += rps;
    }

  /* free any buffers allocated for each plane or scanline and 
   * any temporary buffers 
   */
  for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
    {
    buff = srcbuffs[s];
    if (buff != NULL)
      _TIFFfree(buff);
    }

  return (result);
  } /* end readSeparateStripsIntoBuffer */

Project: libtiff

static int  readSeparateTilesIntoBuffer (TIFF* in, uint8 *obuf, 
					 uint32 imagelength, uint32 imagewidth, 
                                         uint32 tw, uint32 tl,
                                         uint16 spp, uint16 bps)
  {
  int     i, status = 1, sample;
  int     shift_width, bytes_per_pixel;
  uint16  bytes_per_sample;
  uint32  row, col;     /* Current row and col of image */
  uint32  nrow, ncol;   /* Number of rows and cols in current tile */
  uint32  row_offset, col_offset; /* Output buffer offsets */
  tsize_t tbytes = 0, tilesize = TIFFTileSize(in);
  tsample_t s;
  uint8*  bufp = (uint8*)obuf;
  unsigned char *srcbuffs[MAX_SAMPLES];
  unsigned char *tbuff = NULL;

  bytes_per_sample = (bps + 7) / 8;

  for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
    {
    srcbuffs[sample] = NULL;
    tbuff = (unsigned char *)_TIFFmalloc(tilesize + 8);
    if (!tbuff)
      {
      TIFFError ("readSeparateTilesIntoBuffer", 
                 "Unable to allocate tile read buffer for sample %d", sample);
      for (i = 0; i < sample; i++)
        _TIFFfree (srcbuffs[i]);
      return 0;
      }
    srcbuffs[sample] = tbuff;
    } 
  /* Each tile contains only the data for a single plane
   * arranged in scanlines of tw * bytes_per_sample bytes.
   */
  for (row = 0; row < imagelength; row += tl)
    {
    nrow = (row + tl > imagelength) ? imagelength - row : tl;
    for (col = 0; col < imagewidth; col += tw)
      {
      for (s = 0; s < spp && s < MAX_SAMPLES; s++)
        {  /* Read each plane of a tile set into srcbuffs[s] */
	tbytes = TIFFReadTile(in, srcbuffs[s], col, row, 0, s);
        if (tbytes < 0  && !ignore)
          {
	  TIFFError(TIFFFileName(in),
                 "Error, can't read tile for row %lu col %lu, "
		 "sample %lu",
		 (unsigned long) col, (unsigned long) row,
		 (unsigned long) s);
		 status = 0;
          for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
            {
            tbuff = srcbuffs[sample];
            if (tbuff != NULL)
              _TIFFfree(tbuff);
            }
          return status;
	  }
	}
     /* Tiles on the right edge may be padded out to tw 
      * which must be a multiple of 16.
      * Ncol represents the visible (non padding) portion.  
      */
      if (col + tw > imagewidth)
        ncol = imagewidth - col;
      else
        ncol = tw;

      row_offset = row * (((imagewidth * spp * bps) + 7) / 8);
      col_offset = ((col * spp * bps) + 7) / 8;
      bufp = obuf + row_offset + col_offset;

      if ((bps % 8) == 0)
        {
        if (combineSeparateTileSamplesBytes(srcbuffs, bufp, ncol, nrow, imagewidth,
					    tw, spp, bps, NULL, 0, 0))
	  {
          status = 0;
          break;
      	  }
	}
      else
        {
        bytes_per_pixel  = ((bps * spp) + 7) / 8;
        if (bytes_per_pixel < (bytes_per_sample + 1))
          shift_width = bytes_per_pixel;
        else
          shift_width = bytes_per_sample + 1;

        switch (shift_width)
          {
          case 1: if (combineSeparateTileSamples8bits (srcbuffs, bufp, ncol, nrow,
                                                       imagewidth, tw, spp, bps, 
						       NULL, 0, 0))
	            {
                    status = 0;
                    break;
      	            }
	          break;
          case 2: if (combineSeparateTileSamples16bits (srcbuffs, bufp, ncol, nrow,
                                                       imagewidth, tw, spp, bps, 
						       NULL, 0, 0))
	            {
                    status = 0;
                    break;
		    }
	          break;
          case 3: if (combineSeparateTileSamples24bits (srcbuffs, bufp, ncol, nrow,
                                                       imagewidth, tw, spp, bps, 
						       NULL, 0, 0))
	            {
                    status = 0;
                    break;
       	            }
                  break;
          case 4: 
          case 5:
          case 6:
          case 7:
          case 8: if (combineSeparateTileSamples32bits (srcbuffs, bufp, ncol, nrow,
                                                       imagewidth, tw, spp, bps, 
						       NULL, 0, 0))
	            {
                    status = 0;
                    break;
		    }
	          break;
          default: TIFFError ("readSeparateTilesIntoBuffer", "Unsupported bit depth: %d", bps);
                  status = 0;
                  break;
          }
        }
      }
    }

  for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
    {
    tbuff = srcbuffs[sample];
    if (tbuff != NULL)
      _TIFFfree(tbuff);
    }
 
  return status;
  }

Project: libtiff

reverseSamples16bits (uint16 spp, uint16 bps, uint32 width, 
                      uint8 *ibuff, uint8 *obuff)
  {
  int      ready_bits = 0;
  uint32   col;
  uint32   src_byte = 0, high_bit = 0;
  uint32   bit_offset = 0;
  uint16   match_bits = 0, mask_bits = 0;
  uint16   buff1 = 0, buff2 = 0;
  uint8    bytebuff = 0;
  unsigned char *src;
  unsigned char *dst;
  tsample_t sample;

  if ((ibuff == NULL) || (obuff == NULL))
    {
    TIFFError("reverseSample16bits","Invalid image or work buffer");
    return (1);
    }

  ready_bits = 0;
  mask_bits =  (uint16)-1 >> (16 - bps);
  dst = obuff;
  for (col = width; col > 0; col--)
    {
    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = (col - 1) * bps * spp;
    for (sample = 0; sample < spp; sample++)
      {
      if (sample == 0)
        {
        src_byte = bit_offset / 8;
        high_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sample * bps)) / 8;
        high_bit  = (bit_offset + (sample * bps)) % 8;
        }

      src = ibuff + src_byte;
      match_bits = mask_bits << (16 - high_bit - bps); 
      if (little_endian)
        buff1 = (src[0] << 8) | src[1];
      else
        buff1 = (src[1] << 8) | src[0];
      buff1 = (buff1 & match_bits) << (high_bit);
      
      if (ready_bits < 8)
        { /* add another bps bits to the buffer */
        bytebuff = 0;
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      else /* If we have a full buffer's worth, write it out */
        {
        bytebuff = (buff2 >> 8);
        *dst++ = bytebuff;
        ready_bits -= 8;
        /* shift in new bits */
        buff2 = ((buff2 << 8) | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }

  if (ready_bits > 0)
    {
    bytebuff = (buff2 >> 8);
    *dst++ = bytebuff;
    }

  return (0);
  } /* end reverseSamples16bits */

Project: libtiff

reverseSamples24bits (uint16 spp, uint16 bps, uint32 width, 
                      uint8 *ibuff, uint8 *obuff)
  {
  int      ready_bits = 0;
  uint32   col;
  uint32   src_byte = 0, high_bit = 0;
  uint32   bit_offset = 0;
  uint32   match_bits = 0, mask_bits = 0;
  uint32   buff1 = 0, buff2 = 0;
  uint8    bytebuff1 = 0, bytebuff2 = 0;
  unsigned char *src;
  unsigned char *dst;
  tsample_t sample;

  if ((ibuff == NULL) || (obuff == NULL))
    {
    TIFFError("reverseSamples24bits","Invalid image or work buffer");
    return (1);
    }

  ready_bits = 0;
  mask_bits =  (uint32)-1 >> (32 - bps);
  dst = obuff;
  for (col = width; col > 0; col--)
    {
    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = (col - 1) * bps * spp;
    for (sample = 0; sample < spp; sample++)
      {
      if (sample == 0)
        {
        src_byte = bit_offset / 8;
        high_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sample * bps)) / 8;
        high_bit  = (bit_offset + (sample * bps)) % 8;
        }

      src = ibuff + src_byte;
      match_bits = mask_bits << (32 - high_bit - bps); 
      if (little_endian)
	buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
      else
	buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
      buff1 = (buff1 & match_bits) << (high_bit);

      if (ready_bits < 16)
        { /* add another bps bits to the buffer */
        bytebuff1 = bytebuff2 = 0;
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      else /* If we have a full buffer's worth, write it out */
        {
        bytebuff1 = (buff2 >> 24);
        *dst++ = bytebuff1;
        bytebuff2 = (buff2 >> 16);
        *dst++ = bytebuff2;
        ready_bits -= 16;

        /* shift in new bits */
        buff2 = ((buff2 << 16) | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }

 /* catch any trailing bits at the end of the line */
  while (ready_bits > 0)
    {
    bytebuff1 = (buff2 >> 24);
    *dst++ = bytebuff1;

    buff2 = (buff2 << 8);
    bytebuff2 = bytebuff1;
    ready_bits -= 8;
    }
 
  return (0);
  } /* end reverseSamples24bits */

Project: libtiff

reverseSamples8bits (uint16 spp, uint16 bps, uint32 width, 
                     uint8 *ibuff, uint8 *obuff)
  {
  int      ready_bits = 0;
  uint32   col;
  uint32   src_byte, src_bit;
  uint32   bit_offset = 0;
  uint8    match_bits = 0, mask_bits = 0;
  uint8    buff1 = 0, buff2 = 0;
  unsigned char *src;
  unsigned char *dst;
  tsample_t sample;

  if ((ibuff == NULL) || (obuff == NULL))
    {
    TIFFError("reverseSamples8bits","Invalid image or work buffer");
    return (1);
    }

  ready_bits = 0;
  mask_bits =  (uint8)-1 >> ( 8 - bps);
  dst = obuff;
  for (col = width; col > 0; col--)
    {
    /* Compute src byte(s) and bits within byte(s) */
    bit_offset = (col - 1) * bps * spp;
    for (sample = 0; sample < spp; sample++)
      {
      if (sample == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sample * bps)) / 8;
        src_bit  = (bit_offset + (sample * bps)) % 8;
        }

      src = ibuff + src_byte;
      match_bits = mask_bits << (8 - src_bit - bps); 
      buff1 = ((*src) & match_bits) << (src_bit);

      if (ready_bits < 8)
        buff2 = (buff2 | (buff1 >> ready_bits));
      else  /* If we have a full buffer's worth, write it out */
        {
        *dst++ = buff2;
        buff2 = buff1;
        ready_bits -= 8;
        }
      ready_bits += bps;
      }
    }
  if (ready_bits > 0)
    {
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
    *dst++ = buff1;
    }

  return (0);
  } /* end reverseSamples8bits */

Project: libtiff

reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width, 
                     uint8 *src, uint8 *dst)
  {
  int i;
  uint32  col, bytes_per_pixel, col_offset;
  uint8   bytebuff1;
  unsigned char swapbuff[32];
  
  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("reverseSamplesBytes","Invalid input or output buffer");
    return (1);
    }

  bytes_per_pixel  = ((bps * spp) + 7) / 8;
  if( bytes_per_pixel > sizeof(swapbuff) )
  {
    TIFFError("reverseSamplesBytes","bytes_per_pixel too large");
    return (1);
  }
  switch (bps / 8)
     {
     case 8:  /* Use memcpy for multiple bytes per sample data */
     case 4:
     case 3:
     case 2: for (col = 0; col < (width / 2); col++)
               {
	       col_offset = col * bytes_per_pixel;                     
	       _TIFFmemcpy (swapbuff, src + col_offset, bytes_per_pixel);
	       _TIFFmemcpy (src + col_offset, dst - col_offset - bytes_per_pixel, bytes_per_pixel);
	       _TIFFmemcpy (dst - col_offset - bytes_per_pixel, swapbuff, bytes_per_pixel);
               }
	     break;
     case 1: /* Use byte copy only for single byte per sample data */
             for (col = 0; col < (width / 2); col++)
               { 
	       for (i = 0; i < spp; i++)
                  {
		  bytebuff1 = *src;
		  *src++ = *(dst - spp + i);
                  *(dst - spp + i) = bytebuff1;
		  }
		dst -= spp;
                }
	     break;
     default: TIFFError("reverseSamplesBytes","Unsupported bit depth %d", bps);
       return (1);
     }
  return (0);
  } /* end reverseSamplesBytes */

Project: libtiff

rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
                          uint32 length,   uint32 col, uint8 *src, uint8 *dst)
  {
  int    ready_bits = 0 /*, shift_width = 0 */;
  /* int    bytes_per_sample, bytes_per_pixel; */
  uint32 row, rowsize, bit_offset;
  uint32 src_byte, src_bit;
  uint32 longbuff1 = 0, longbuff2 = 0;
  uint64 maskbits = 0, matchbits = 0;
  uint64 buff1 = 0, buff2 = 0, buff3 = 0;
  uint8  bytebuff1 = 0, bytebuff2 = 0, bytebuff3 = 0, bytebuff4 = 0;
  uint8   *next;
  tsample_t sample;


  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("rotateContigSamples24bits","Invalid src or destination buffer");
    return (1);
    }

  /* bytes_per_sample = (bps + 7) / 8; */
  /* bytes_per_pixel  = ((bps * spp) + 7) / 8; */
  /* if (bytes_per_pixel < (bytes_per_sample + 1)) */
  /*   shift_width = bytes_per_pixel; */
  /* else */
  /*   shift_width = bytes_per_sample + 1; */

  rowsize = ((bps * spp * width) + 7) / 8;
  ready_bits = 0;
  maskbits =  (uint64)-1 >> (64 - bps);
  buff1 = buff2 = 0;
  for (row = 0; row < length; row++)
    {
    bit_offset = col * bps * spp;
    for (sample = 0; sample < spp; sample++)
      {
      if (sample == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sample * bps)) / 8;
        src_bit  = (bit_offset + (sample * bps)) % 8;
        }

      switch (rotation)
	{
        case  90: next = src + src_byte - (row * rowsize);
                  break;
        case 270: next = src + src_byte + (row * rowsize);
	          break;
	default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
                  return (1);
        }
      matchbits = maskbits << (64 - src_bit - bps); 
      if (little_endian)
        {
	longbuff1 = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | next[3];
        longbuff2 = longbuff1;
        }
      else
        {
	longbuff1 = (next[3] << 24) | (next[2] << 16) | (next[1] << 8) | next[0];
        longbuff2 = longbuff1;
	}

      buff3 = ((uint64)longbuff1 << 32) | longbuff2;
      buff1 = (buff3 & matchbits) << (src_bit);

      if (ready_bits < 32)
        { /* add another bps bits to the buffer */
        bytebuff1 = bytebuff2 = bytebuff3 = bytebuff4 = 0;
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      else /* If we have a full buffer's worth, write it out */
        {
        bytebuff1 = (buff2 >> 56);
        *dst++ = bytebuff1;
        bytebuff2 = (buff2 >> 48);
        *dst++ = bytebuff2;
        bytebuff3 = (buff2 >> 40);
        *dst++ = bytebuff3;
        bytebuff4 = (buff2 >> 32);
        *dst++ = bytebuff4;
        ready_bits -= 32;
                    
        /* shift in new bits */
        buff2 = ((buff2 << 32) | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }
  while (ready_bits > 0)
    {
    bytebuff1 = (buff2 >> 56);
    *dst++ = bytebuff1;
    buff2 = (buff2 << 8);
    ready_bits -= 8;
    }

  return (0);
  } /* end rotateContigSamples32bits */

Project: libtiff

rotateContigSamples8bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width, 
                         uint32 length,   uint32 col, uint8 *src, uint8 *dst)
  {
  int      ready_bits = 0;
  uint32   src_byte = 0, src_bit = 0;
  uint32   row, rowsize = 0, bit_offset = 0;
  uint8    matchbits = 0, maskbits = 0;
  uint8    buff1 = 0, buff2 = 0;
  uint8   *next;
  tsample_t sample;

  if ((src == NULL) || (dst == NULL))
    {
    TIFFError("rotateContigSamples8bits","Invalid src or destination buffer");
    return (1);
    }

  rowsize = ((bps * spp * width) + 7) / 8;
  ready_bits = 0;
  maskbits =  (uint8)-1 >> ( 8 - bps);
  buff1 = buff2 = 0;

  for (row = 0; row < length ; row++)
    {
    bit_offset = col * bps * spp;
    for (sample = 0; sample < spp; sample++)
      {
      if (sample == 0)
        {
        src_byte = bit_offset / 8;
        src_bit  = bit_offset % 8;
        }
      else
        {
        src_byte = (bit_offset + (sample * bps)) / 8;
        src_bit  = (bit_offset + (sample * bps)) % 8;
        }

      switch (rotation)
	{
        case  90: next = src + src_byte - (row * rowsize);
                  break;
        case 270: next = src + src_byte + (row * rowsize);
	          break;
	default:  TIFFError("rotateContigSamples8bits", "Invalid rotation %d", rotation);
                  return (1);
        }
      matchbits = maskbits << (8 - src_bit - bps); 
      buff1 = ((*next) & matchbits) << (src_bit);

       /* If we have a full buffer's worth, write it out */
      if (ready_bits >= 8)
        {
        *dst++ = buff2;
        buff2 = buff1;
        ready_bits -= 8;
        }
      else
        {
        buff2 = (buff2 | (buff1 >> ready_bits));
        }
      ready_bits += bps;
      }
    }

  if (ready_bits > 0)
    {
    buff1 = (buff2 & ((unsigned int)255 << (8 - ready_bits)));
    *dst++ = buff1;
    }

  return (0);
  }  /* end rotateContigSamples8bits */

Project: libtiff

rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width, 
            uint32 *img_length, unsigned char **ibuff_ptr)
  {
  int      shift_width;
  uint32   bytes_per_pixel, bytes_per_sample;
  uint32   row, rowsize, src_offset, dst_offset;
  uint32   i, col, width, length;
  uint32   colsize, buffsize, col_offset, pix_offset;
  unsigned char *ibuff;
  unsigned char *src;
  unsigned char *dst;
  uint16   spp, bps;
  float    res_temp;
  unsigned char *rbuff = NULL;

  width  = *img_width;
  length = *img_length;
  spp = image->spp;
  bps = image->bps;

  rowsize = ((bps * spp * width) + 7) / 8;
  colsize = ((bps * spp * length) + 7) / 8;
  if ((colsize * width) > (rowsize * length))
    buffsize = (colsize + 1) * width;
  else
    buffsize = (rowsize + 1) * length;

  bytes_per_sample = (bps + 7) / 8;
  bytes_per_pixel  = ((bps * spp) + 7) / 8;
  if (bytes_per_pixel < (bytes_per_sample + 1))
    shift_width = bytes_per_pixel;
  else
    shift_width = bytes_per_sample + 1;

  switch (rotation)
    {
    case 0:
    case 360: return (0);
    case 90:
    case 180:
    case 270: break;
    default:  TIFFError("rotateImage", "Invalid rotation angle %d", rotation);
              return (-1);
    }

  if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize)))
    {
    TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize);
    return (-1);
    }
  _TIFFmemset(rbuff, '\0', buffsize);

  ibuff = *ibuff_ptr;
  switch (rotation)
    {
    case 180: if ((bps % 8) == 0) /* byte alligned data */
                { 
                src = ibuff;
                pix_offset = (spp * bps) / 8;
                for (row = 0; row < length; row++)
                   {
		   dst_offset = (length - row - 1) * rowsize;
                   for (col = 0; col < width; col++)
                     { 
		     col_offset = (width - col - 1) * pix_offset;
                     dst = rbuff + dst_offset + col_offset;

		     for (i = 0; i  < bytes_per_pixel; i++)
		       *dst++ = *src++;
                     }
                   }
                }
	      else
                { /* non 8 bit per sample data */ 
                for (row = 0; row < length; row++)
                  {
		  src_offset = row * rowsize;
		  dst_offset = (length - row - 1) * rowsize;
		  src = ibuff + src_offset;
                  dst = rbuff + dst_offset;
                  switch (shift_width)
                    {
                    case 1: if (bps == 1)
			      {
                              if (reverseSamples8bits(spp, bps, width, src, dst))
                                {
		                _TIFFfree(rbuff);
                                return (-1);
                                }
                              break;
                              }
                            if (reverseSamples16bits(spp, bps, width, src, dst))
                              {
		              _TIFFfree(rbuff);
                              return (-1);
                              }
                             break;
                    case 2: if (reverseSamples24bits(spp, bps, width, src, dst))
                              {
		              _TIFFfree(rbuff);
                              return (-1);
                              }
                             break;
                    case 3: 
                    case 4: 
                    case 5: if (reverseSamples32bits(spp, bps, width, src, dst))
                              {
		              _TIFFfree(rbuff);
                              return (-1);
                              }
                             break;
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
		             _TIFFfree(rbuff);
                             return (-1);      
                    }
		  }
		}
              _TIFFfree(ibuff);
              *(ibuff_ptr) = rbuff;
              break;

    case 90:  if ((bps % 8) == 0) /* byte aligned data */
                {
                for (col = 0; col < width; col++)
                  {
		  src_offset = ((length - 1) * rowsize) + (col * bytes_per_pixel);
                  dst_offset = col * colsize;
		  src = ibuff + src_offset;
		  dst = rbuff + dst_offset;
                  for (row = length; row > 0; row--)
                    {
                    for (i = 0; i < bytes_per_pixel; i++)
                      *dst++ = *(src + i);
		    src -= rowsize;
                    }
		  }
		}
              else
                { /* non 8 bit per sample data */ 
                for (col = 0; col < width; col++)
                  {
		  src_offset = (length - 1) * rowsize;
                  dst_offset = col * colsize;
		  src = ibuff + src_offset;
		  dst = rbuff + dst_offset;
                  switch (shift_width)
                    {
                    case 1: if (bps == 1)
			      {
                              if (rotateContigSamples8bits(rotation, spp, bps, width, 
				   	                 length, col, src, dst))
                                {
		                _TIFFfree(rbuff);
                                return (-1);
                                }
                              break;
                              }
                            if (rotateContigSamples16bits(rotation, spp, bps, width, 
				   	                 length, col, src, dst))
                              {
	                      _TIFFfree(rbuff);
                              return (-1);
		              }
		            break;
                    case 2: if (rotateContigSamples24bits(rotation, spp, bps, width, 
					                  length, col, src, dst))
                              {
		              _TIFFfree(rbuff);
                              return (-1);
                              }
                             break;
                    case 3: 
                    case 4: 
                    case 5: if (rotateContigSamples32bits(rotation, spp, bps, width, 
					                  length, col, src, dst))
                              {
		              _TIFFfree(rbuff);
                              return (-1);
                              }
                             break;
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
		             _TIFFfree(rbuff);
                             return (-1);      
		    }
		  }
		}
              _TIFFfree(ibuff);
              *(ibuff_ptr) = rbuff;

              *img_width = length;
              *img_length = width;
              image->width = length;
              image->length = width;
              res_temp = image->xres;
              image->xres = image->yres;
              image->yres = res_temp;
	      break;

    case 270: if ((bps % 8) == 0) /* byte aligned data */
                {
                for (col = 0; col < width; col++)
                  {
		  src_offset = col * bytes_per_pixel;
                  dst_offset = (width - col - 1) * colsize;
		  src = ibuff + src_offset;
		  dst = rbuff + dst_offset;
                  for (row = length; row > 0; row--)
                    {
                    for (i = 0; i < bytes_per_pixel; i++)
                      *dst++ = *(src + i);
		    src += rowsize;
                    }
		  }
		}
              else
                { /* non 8 bit per sample data */ 
                for (col = 0; col < width; col++)
                  {
		  src_offset = 0;
                  dst_offset = (width - col - 1) * colsize;
		  src = ibuff + src_offset;
		  dst = rbuff + dst_offset;
                  switch (shift_width)
                    {
                    case 1: if (bps == 1)
			      {
                              if (rotateContigSamples8bits(rotation, spp, bps, width, 
				   	                 length, col, src, dst))
                                {
		                _TIFFfree(rbuff);
                                return (-1);
                                }
                              break;
                              }
                            if (rotateContigSamples16bits(rotation, spp, bps, width, 
				   	                 length, col, src, dst))
                              {
	                      _TIFFfree(rbuff);
                              return (-1);
		              }
		            break;
                    case 2: if (rotateContigSamples24bits(rotation, spp, bps, width, 
					                  length, col, src, dst))
                              {
		              _TIFFfree(rbuff);
                              return (-1);
                              }
                             break;
                    case 3: 
                    case 4: 
                    case 5: if (rotateContigSamples32bits(rotation, spp, bps, width, 
					                  length, col, src, dst))
                              {
		              _TIFFfree(rbuff);
                              return (-1);
                              }
                             break;
                    default: TIFFError("rotateImage","Unsupported bit depth %d", bps);
		             _TIFFfree(rbuff);
                             return (-1);      
		    }
		  }
		}
              _TIFFfree(ibuff);
              *(ibuff_ptr) = rbuff;

              *img_width = length;
              *img_length = width;
              image->width = length;
              image->length = width;
              res_temp = image->xres;
              image->xres = image->yres;
              image->yres = res_temp;
              break;
    default:
              break;
    }

  return (0);
  } /* end rotateImage */

Project: libtiff

update_output_file (TIFF **tiffout, char *mode, int autoindex,
                    char *outname, unsigned int *page)
  {
  static int findex = 0;    /* file sequence indicator */
  char  *sep;
  char   filenum[16];
  char   export_ext[16];
  char   exportname[PATH_MAX];

  if (autoindex && (*tiffout != NULL))
    {   
    /* Close any export file that was previously opened */
    TIFFClose (*tiffout);
    *tiffout = NULL;
    }

  strcpy (export_ext, ".tiff");
  memset (exportname, '\0', PATH_MAX);

  /* Leave room for page number portion of the new filename */
  strncpy (exportname, outname, PATH_MAX - 16);
  if (*tiffout == NULL)   /* This is a new export file */
    {
    if (autoindex)
      { /* create a new filename for each export */
      findex++;
      if ((sep = strstr(exportname, ".tif")) || (sep = strstr(exportname, ".TIF")))
        {
        strncpy (export_ext, sep, 5);
        *sep = '\0';
        }
      else
        strncpy (export_ext, ".tiff", 5);
      export_ext[5] = '\0';

      /* MAX_EXPORT_PAGES limited to 6 digits to prevent string overflow of pathname */
      if (findex > MAX_EXPORT_PAGES)
	{
	TIFFError("update_output_file", "Maximum of %d pages per file exceeded", MAX_EXPORT_PAGES);
        return 1;
        }

      snprintf(filenum, sizeof(filenum), "-%03d%s", findex, export_ext);
      filenum[14] = '\0';
      strncat (exportname, filenum, 15);
      }
    exportname[PATH_MAX - 1] = '\0';

    *tiffout = TIFFOpen(exportname, mode);
    if (*tiffout == NULL)
      {
      TIFFError("update_output_file", "Unable to open output file %s", exportname);
      return 1;
      }
    *page = 0; 

    return 0;
    }
  else 
    (*page)++;

  return 0;
  } /* end update_output_file */

Project: libtiff

usage(void)
  {
  int i;

  fprintf(stderr, "\n%s\n", TIFFGetVersion());
  for (i = 0; usage_info[i] != NULL; i++)
    fprintf(stderr, "%s\n", usage_info[i]);
  exit(-1);
  }

Project: libtiff

static int writeBufferToContigStrips(TIFF* out, uint8* buf, uint32 imagelength)
  {
  uint32 row, nrows, rowsperstrip;
  tstrip_t strip = 0;
  tsize_t stripsize;

  TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  for (row = 0; row < imagelength; row += rowsperstrip)
    {
    nrows = (row + rowsperstrip > imagelength) ?
	     imagelength - row : rowsperstrip;
    stripsize = TIFFVStripSize(out, nrows);
    if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0)
      {
      TIFFError(TIFFFileName(out), "Error, can't write strip %u", strip - 1);
      return 1;
      }
    buf += stripsize;
    }

  return 0;
  }