Ejemplo n.º 1
0
static void get_image_dimensions(ImageSize *is, int *width, int *height)
{
	unsigned int length;
	unsigned int image_height, image_width;
	int          num_components;
	int          ci;

	length = read_2_bytes(is);

	read_1_byte(is); /* data_precision */
	image_height = read_2_bytes(is);
	image_width = read_2_bytes(is);
	num_components = read_1_byte(is);

	*width = image_width;
	*height = image_height;

	if (length != (unsigned int) (8 + num_components * 3)) {
		*width = *height = -1;  /* Bogus SOF marker length */
	} else {
		for (ci = 0; ci < num_components; ci++) {
			read_1_byte(is);	/* Component ID code */
			read_1_byte(is);	/* H, V sampling factors */
			read_1_byte(is);	/* Quantization table number */
		}
	}
}
Ejemplo n.º 2
0
static void
process_SOFn (int marker)
{
  unsigned int length;
  unsigned int image_height, image_width;
  int data_precision, num_components;
  const char * process;
  int ci;

  length = read_2_bytes();	/* usual parameter length count */

  data_precision = read_1_byte();
  image_height = read_2_bytes();
  image_width = read_2_bytes();
  num_components = read_1_byte();

  switch (marker) {
  case M_SOF0:	process = "Baseline";  break;
  case M_SOF1:	process = "Extended sequential";  break;
  case M_SOF2:	process = "Progressive";  break;
  case M_SOF3:	process = "Lossless";  break;
  case M_SOF5:	process = "Differential sequential";  break;
  case M_SOF6:	process = "Differential progressive";  break;
  case M_SOF7:	process = "Differential lossless";  break;
  case M_SOF9:	process = "Extended sequential, arithmetic coding";  break;
  case M_SOF10:	process = "Progressive, arithmetic coding";  break;
  case M_SOF11:	process = "Lossless, arithmetic coding";  break;
  case M_SOF13:	process = "Differential sequential, arithmetic coding";  break;
  case M_SOF14:	process = "Differential progressive, arithmetic coding"; break;
  case M_SOF15:	process = "Differential lossless, arithmetic coding";  break;
  default:	process = "Unknown";  break;
  }

  printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n",
	 image_width, image_height, num_components, data_precision);
  printf("JPEG process: %s\n", process);

  if (length != (unsigned int) (8 + num_components * 3))
    ERREXIT("Bogus SOF marker length");

  for (ci = 0; ci < num_components; ci++) {
    (void) read_1_byte();	/* Component ID code */
    (void) read_1_byte();	/* H, V sampling factors */
    (void) read_1_byte();	/* Quantization table number */
  }
}
Ejemplo n.º 3
0
 uint64_t read_variable_uint()
 {
     uint8_t length = read_byte();
     uint64_t value = 0;
     if (length < 0xfd)
         value = length;
     else if (length == 0xfd)
         value += read_2_bytes();
     else if (length == 0xfe)
         value += read_4_bytes();
     else if (length == 0xff)
         value += read_8_bytes();
     return value;
 }
Ejemplo n.º 4
0
static void
process_COM (int raw)
{
  unsigned int length;
  int ch;
  int lastch = 0;

  /* Bill Allombert: set locale properly for isprint */
#ifdef HAVE_LOCALE_H
  setlocale(LC_CTYPE, "");
#endif

  /* Get the marker parameter length count */
  length = read_2_bytes();
  /* Length includes itself, so must be at least 2 */
  if (length < 2)
    ERREXIT("Erroneous JPEG marker length");
  length -= 2;

  while (length > 0) {
    ch = read_1_byte();
    if (raw) {
      putc(ch, stdout);
    /* Emit the character in a readable form.
     * Nonprintables are converted to \nnn form,
     * while \ is converted to \\.
     * Newlines in CR, CR/LF, or LF form will be printed as one newline.
     */
    } else if (ch == '\r') {
      printf("\n");
    } else if (ch == '\n') {
      if (lastch != '\r')
	printf("\n");
    } else if (ch == '\\') {
      printf("\\\\");
    } else if (isprint(ch)) {
      putc(ch, stdout);
    } else {
      printf("\\%03o", ch);
    }
    lastch = ch;
    length--;
  }
  printf("\n");

  /* Bill Allombert: revert to C locale */
#ifdef HAVE_LOCALE_H
  setlocale(LC_CTYPE, "C");
#endif
}
Ejemplo n.º 5
0
static void
process_COM (void)
{
  unsigned int length;
  int ch;
  int lastch = 0;

  /* Get the marker parameter length count */
  length = read_2_bytes();
  /* Length includes itself, so must be at least 2 */
  if (length < 2)
    ERREXIT("Erroneous JPEG marker length");
  length -= 2;

  while (length > 0)
  {
    ch = read_1_byte();
    /* Emit the character in a readable form.
     * Nonprintables are converted to \nnn form,
     * while \ is converted to \\.
     * Newlines in CR, CR/LF, or LF form will be printed as one newline.
     */
    if (ch == '\r')
    {
      printf("\n");
    }
    else if (ch == '\n')
    {
      if (lastch != '\r')
        printf("\n");
    }
    else if (ch == '\\')
    {
      printf("\\\\");
    }
    else if (isprint(ch))
    {
      putc(ch, stdout);
    }
    else
    {
      printf("\\%03o", ch);
    }
    lastch = ch;
    length--;
  }
  printf("\n");
}
Ejemplo n.º 6
0
static void
skip_variable (void)
/* Skip over an unknown or uninteresting variable-length marker */
{
  unsigned int length;

  /* Get the marker parameter length count */
  length = read_2_bytes();
  /* Length includes itself, so must be at least 2 */
  if (length < 2)
    ERREXIT("Erroneous JPEG marker length");
  length -= 2;
  /* Skip over the remaining bytes */
  while (length > 0) {
    (void) read_1_byte();
    length--;
  }
}
Ejemplo n.º 7
0
/* Skip over an unknown or uninteresting variable-length marker */
static int skip_variable(ImageSize *is)
{
	int length;
	int res = 0;

	/* Get the marker parameter length count */
	length = read_2_bytes(is);
	/* Length includes itself, so must be at least 2 */
	if (length < 2 || length == EOF) {
		res = -1; /* error */
	} else {
		length -= 2;
		/* Skip over the remaining bytes */
		while (length > 0) {
			read_1_byte(is);
			length--;
		}
	}
	return res;
}
unsigned int GetOrientationOfFile(char * filename)
{
  read_byte_error_while_reading=0;
  myfile=0;
  int n_flag=0 , set_flag=0;
  unsigned int length=0, i=0;
  int is_motorola=0; /* Flag for byte order */
  unsigned int offset=0, number_of_tags=0, tagnum=0;



  n_flag = 0; set_flag = 0;

  i = 1;
  myfile = fopen(filename, "rb");
    if ( myfile == 0)
    {
      fprintf(stderr, " Can't open %s\n", filename);
      return 0;
    }

  /* Read File head, check for JPEG SOI + Exif APP1 */
  for (i = 0; i < 4; i++) { exif_data[i] = (unsigned char) read_1_byte(); }

  if (exif_data[0] != 0xFF ||
      exif_data[1] != 0xD8 ||
      exif_data[2] != 0xFF ||
      exif_data[3] != 0xE1) { fclose(myfile); return 0; }

  /* Get the marker parameter length count */
  length = read_2_bytes();
  /* Length includes itself, so must be at least 2 */
  /* Following Exif data length must be at least 6 */
  if (length < 8) { fclose(myfile); return 0; }
  length -= 8;
  /* Read Exif head, check for "Exif" */
  for (i = 0; i < 6; i++) { exif_data[i] = (unsigned char) read_1_byte(); }

  if (exif_data[0] != 0x45 ||
      exif_data[1] != 0x78 ||
      exif_data[2] != 0x69 ||
      exif_data[3] != 0x66 ||
      exif_data[4] != 0 ||
      exif_data[5] != 0) { fclose(myfile); return 0; }

  /* Read Exif body */
  for (i = 0; i < length; i++) { exif_data[i] = (unsigned char) read_1_byte(); }


  if (length < 12) { fclose(myfile); return 0; } /* Length of an IFD entry */

  /* Discover byte order */
  if (exif_data[0] == 0x49 && exif_data[1] == 0x49) { is_motorola = 0; } else
  if (exif_data[0] == 0x4D && exif_data[1] == 0x4D) { is_motorola = 1; } else
                                                    { fclose(myfile); return 0; }

  /* Check Tag Mark */
  if (is_motorola)
  {
    if (exif_data[2] != 0)    { fclose(myfile); return 0; }
    if (exif_data[3] != 0x2A) { fclose(myfile); return 0; }
  } else
  {
    if (exif_data[3] != 0)    { fclose(myfile); return 0; }
    if (exif_data[2] != 0x2A) { fclose(myfile); return 0; }
  }

  /* Get first IFD offset (offset to IFD0) */
  if (is_motorola)
  {
    if (exif_data[4] != 0) { fclose(myfile); return 0; }
    if (exif_data[5] != 0) { fclose(myfile); return 0; }
    offset = exif_data[6];
    offset <<= 8;
    offset += exif_data[7];
  } else
  {
    if (exif_data[7] != 0) { fclose(myfile); return 0; }
    if (exif_data[6] != 0) { fclose(myfile); return 0; }
    offset = exif_data[5];
    offset <<= 8;
    offset += exif_data[4];
  }

  if (offset > length - 2) { fclose(myfile); return 0; } /* check end of data segment */

  /* Get the number of directory entries contained in this IFD */
  if (is_motorola)
  {
    number_of_tags = exif_data[offset];
    number_of_tags <<= 8;
    number_of_tags += exif_data[offset+1];
  } else
  {
    number_of_tags = exif_data[offset+1];
    number_of_tags <<= 8;
    number_of_tags += exif_data[offset];
  }
  if (number_of_tags == 0) { fclose(myfile); return 0; }
  offset += 2;

  /* Search for Orientation Tag in IFD0 */
  for (;;)
  {
    if (offset > length - 12) { fclose(myfile); return 0; }/* check end of data segment */
    /* Get Tag number */
    if (is_motorola)
    {
      tagnum = exif_data[offset];
      tagnum <<= 8;
      tagnum += exif_data[offset+1];
    } else
    {
      tagnum = exif_data[offset+1];
      tagnum <<= 8;
      tagnum += exif_data[offset];
    }
    if (tagnum == 0x0112) break; /* found Orientation Tag */
    if (--number_of_tags == 0) { fclose(myfile); return 0; }
    offset += 12;
  }



    /* Get the Orientation value */
    if (is_motorola)
    {
      if (exif_data[offset+8] != 0) { fclose(myfile); return 0; }
      set_flag = exif_data[offset+9];
    } else
    {
      if (exif_data[offset+9] != 0) { fclose(myfile); return 0; }
      set_flag = exif_data[offset+8];
    }
    if (set_flag > 8) { fclose(myfile); return 0; }

    fclose(myfile);
  /* All done. */
  return (unsigned int) set_flag;
}
Ejemplo n.º 9
0
int
main (int argc, char **argv)
{
  int n_flag, set_flag, exif_flag;
  unsigned int length, i;
  int is_motorola; /* Flag for byte order */
  unsigned int offset, number_of_tags, tagnum;

  progname = argv[0];
  if (progname == NULL || progname[0] == 0)
    progname = "jpegexiforient";	/* in case C library doesn't provide it */

  if (argc < 2) { usage(stderr); return 1; }

  n_flag = 0; set_flag = 0;

  i = 1;
  while (argv[i][0] == '-') {
    switch (argv[i][1]) {
    case '-': 
      switch (argv[i][2]) {
      case 'h': usage(stdout); return 0;
      case 'v': fprintf(stdout,"jpegexiforient\n"); return 0;
      default:  usage(stderr); return 1;
      }
    case 'n':
      n_flag = 1;
      break;
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
      set_flag = argv[i][1] - '0';
      break;
    default:
      usage(stderr); return 1;
    }
    if (++i >= argc) { usage(stderr); return 1; }
  }

  if (set_flag) {
    if ((myfile = fopen(argv[i], "rb+")) == NULL) {
      fprintf(stderr, "%s: can't open %s\n", progname, argv[i]);
      return 0;
    }
  } else {
    if ((myfile = fopen(argv[i], "rb")) == NULL) {
      fprintf(stderr, "%s: can't open %s\n", progname, argv[i]);
      return 0;
    }
  }

  /* Read File head, check for JPEG SOI + Exif APP1 or APP0 */
  for (i = 0; i < 4; i++)
    exif_data[i] = (unsigned char) read_1_byte();
  if (exif_data[0] != 0xFF ||
      exif_data[1] != 0xD8 ||
      exif_data[2] != 0xFF)
    return 0;
  if (exif_data[3] != 0xE1)  /* if file header is APP0, skip over the JFIF header and find the Exif header */
  {
      exif_flag = 0;
      while (exif_flag == 0)
      {
        exif_data[0] = (unsigned char) read_1_byte();
        if (exif_data[0] == 0xFF)
        {
            exif_data[0] = (unsigned char) read_1_byte();
            if (exif_data[0] == 0xE1) exif_flag = 1;
        }
      }
  }
      

  /* Get the marker parameter length count */
  length = read_2_bytes();
  /* Length includes itself, so must be at least 2 */
  /* Following Exif data length must be at least 6 */
  if (length < 8)
    return 0;
  length -= 8;
  /* Read Exif head, check for "Exif" */
  for (i = 0; i < 6; i++)
    exif_data[i] = (unsigned char) read_1_byte();
  if (exif_data[0] != 0x45 ||
      exif_data[1] != 0x78 ||
      exif_data[2] != 0x69 ||
      exif_data[3] != 0x66 ||
      exif_data[4] != 0 ||
      exif_data[5] != 0)
    return 0;
  /* Read Exif body */
  for (i = 0; i < length; i++)
    exif_data[i] = (unsigned char) read_1_byte();

  if (length < 12) return 0; /* Length of an IFD entry */

  /* Discover byte order */
  if (exif_data[0] == 0x49 && exif_data[1] == 0x49)
    is_motorola = 0;
  else if (exif_data[0] == 0x4D && exif_data[1] == 0x4D)
    is_motorola = 1;
  else
    return 0;

  /* Check Tag Mark */
  if (is_motorola) {
    if (exif_data[2] != 0) return 0;
    if (exif_data[3] != 0x2A) return 0;
  } else {
    if (exif_data[3] != 0) return 0;
    if (exif_data[2] != 0x2A) return 0;
  }

  /* Get first IFD offset (offset to IFD0) */
  if (is_motorola) {
    if (exif_data[4] != 0) return 0;
    if (exif_data[5] != 0) return 0;
    offset = exif_data[6];
    offset <<= 8;
    offset += exif_data[7];
  } else {
    if (exif_data[7] != 0) return 0;
    if (exif_data[6] != 0) return 0;
    offset = exif_data[5];
    offset <<= 8;
    offset += exif_data[4];
  }
  if (offset > length - 2) return 0; /* check end of data segment */

  /* Get the number of directory entries contained in this IFD */
  if (is_motorola) {
    number_of_tags = exif_data[offset];
    number_of_tags <<= 8;
    number_of_tags += exif_data[offset+1];
  } else {
    number_of_tags = exif_data[offset+1];
    number_of_tags <<= 8;
    number_of_tags += exif_data[offset];
  }
  if (number_of_tags == 0) return 0;
  offset += 2;

  /* Search for Orientation Tag in IFD0 */
  for (;;) {
    if (offset > length - 12) return 0; /* check end of data segment */
    /* Get Tag number */
    if (is_motorola) {
      tagnum = exif_data[offset];
      tagnum <<= 8;
      tagnum += exif_data[offset+1];
    } else {
      tagnum = exif_data[offset+1];
      tagnum <<= 8;
      tagnum += exif_data[offset];
    }
    if (tagnum == 0x0112) break; /* found Orientation Tag */
    if (--number_of_tags == 0) return 0;
    offset += 12;
  }

  if (set_flag) {
    /* Set the Orientation value */
    if (is_motorola) {
      exif_data[offset+2] = 0; /* Format = unsigned short (2 octets) */
      exif_data[offset+3] = 3;
      exif_data[offset+4] = 0; /* Number Of Components = 1 */
      exif_data[offset+5] = 0;
      exif_data[offset+6] = 0;
      exif_data[offset+7] = 1;
      exif_data[offset+8] = 0;
      exif_data[offset+9] = (unsigned char)set_flag;
      exif_data[offset+10] = 0;
      exif_data[offset+11] = 0;
    } else {
      exif_data[offset+2] = 3; /* Format = unsigned short (2 octets) */
      exif_data[offset+3] = 0;
      exif_data[offset+4] = 1; /* Number Of Components = 1 */
      exif_data[offset+5] = 0;
      exif_data[offset+6] = 0;
      exif_data[offset+7] = 0;
      exif_data[offset+8] = (unsigned char)set_flag;
      exif_data[offset+9] = 0;
      exif_data[offset+10] = 0;
      exif_data[offset+11] = 0;
    }
    fseek(myfile, (4 + 2 + 6 + 2) + offset, SEEK_SET);
    fwrite(exif_data + 2 + offset, 1, 10, myfile);
  } else {
    /* Get the Orientation value */
    if (is_motorola) {
      if (exif_data[offset+8] != 0) return 0;
      set_flag = exif_data[offset+9];
    } else {
      if (exif_data[offset+9] != 0) return 0;
      set_flag = exif_data[offset+8];
    }
    if (set_flag > 8) return 0;
  }

  /* Write out Orientation value */
  if (n_flag)
    printf("%c", '0' + set_flag);
  else
    printf("%c\n", '0' + set_flag);

  /* All done. */
  return 0;
}