/** * \brief Sets a Register of the TDC-GP22. * \param[in] reg is the readable register of the GP22. * \param[out] value is a pointer to the storage of the register value. * \param[in] len indicates how many bytes have to read. * \return FALSE if the SPI transmission get a time out. */ uint8_t bsp_GP22RegRead(uint8_t reg, uint32_t *value, uint8_t len) { uint8_t success; uint8_t tx_bytes[5]; uint8_t rx_bytes[5]; assert(GP22_IS_RD(reg)); assert(len==2 || len==4); /* First send a read command */ tx_bytes[0] = reg; success = bsp_SPITransmitBlocked(BSP_SPI_CS_GP22, tx_bytes, len+1, rx_bytes); /* Transform received bytes to a 32 bit integer */ if (success) { if (len == 2) { *value = bytes2short(&(rx_bytes[1])); } else if (len == 4) { *value = bytes2long(&(rx_bytes[1])); } else { success = 0; } } return success; }
/* Reads a long from the file */ static uint32_t read_long(struct tiff_file_desc *tfd, bool *error) { uint32_t value = -1; if (tfd != NULL && tfd->file != NULL && !*error) { uint8_t buf[4]; size_t ret; ret = fread(buf, 1, sizeof(buf), tfd->file); if (ret != sizeof(buf)) *error = true; else value = bytes2long(buf, tfd->is_le); } else *error = true; return value; }
/* Reads an IFD entry and updates the right tiff fields */ static void read_ifd_entry(struct tiff_file_desc *tfd, bool *error) { if (error == NULL || *error) return; uint16_t tag; uint16_t type; uint32_t count; uint32_t offset; uint32_t value; uint32_t next_value = 0; uint32_t cur_pos; uint8_t buf[4]; size_t ret; /* Identification tag */ tag = read_short(tfd, error); /* Type */ type = read_short(tfd, error); /* Number of values */ count = read_long(tfd, error); /* Value */ ret = fread(buf, 1, sizeof(buf), tfd->file); if (ret != sizeof(buf)) *error = true; offset = bytes2long(buf, tfd->is_le); switch (type) { case BYTE: value = buf[0]; break; case SHORT: value = bytes2short(buf, tfd->is_le); uint8_t *next_buf = &buf[2]; next_value = bytes2short(next_buf, tfd->is_le); break; case LONG: value = offset; break; /* Unused values */ case ASCII: case RATIONAL: default: value = 0; } switch(tag) { /* ImageWidth */ case 0x0100: tfd->width = value; break; /* ImageLength */ case 0x0101: tfd->height = value; break; /* BitsPerSample */ case 0x0102: if (count <= 2) tfd->bits_per_sample = value; else { cur_pos = ftell(tfd->file); fseek(tfd->file, offset, SEEK_SET); tfd->bits_per_sample = read_short(tfd, error); fseek(tfd->file, cur_pos, SEEK_SET); } break; /* Compression */ case 0x0103: tfd->compression = value; break; /* PhotometricInterpretation */ case 0x0106: tfd->photometric_interpretation = value; break; /* StripOffsets */ case 0x0111: tfd->nb_strips = count; tfd->strip_offsets = calloc(count, sizeof(uint32_t)); if (tfd->strip_offsets == NULL) { *error = true; return; } if ((count > 1 && type == LONG) || (count > 2 && type == SHORT)) { cur_pos = ftell(tfd->file); fseek(tfd->file, offset, SEEK_SET); for (uint32_t i = 0; i < count; ++i) tfd->strip_offsets[i] = read_long(tfd, error); fseek(tfd->file, cur_pos, SEEK_SET); } else if (type == SHORT && count == 2) { tfd->strip_offsets[0] = value; tfd->strip_offsets[1] = next_value; } else tfd->strip_offsets[0] = value; break; /* SamplesPerPixel */ case 0x0115: tfd->samples_per_pixels = value; break; /* RowsPerStrip */ case 0x0116: /* * Big values mean infinity, * in which case there are no strips */ if (value > 0xFFFFFF) value = 0; tfd->rows_per_strip = value; break; /* StripByteCounts */ case 0x0117: tfd->strip_bytes_count = count; tfd->strip_bytes = calloc(count, sizeof(uint32_t)); if (tfd->strip_bytes == NULL) { *error = true; return; } if ((count > 1 && type == LONG) || (count > 2 && type == SHORT)) { cur_pos = ftell(tfd->file); fseek(tfd->file, offset, SEEK_SET); for (uint32_t i = 0; i < count; ++i) tfd->strip_bytes[i] = read_long(tfd, error); fseek(tfd->file, cur_pos, SEEK_SET); } else if (type == SHORT && count == 2) { tfd->strip_bytes[0] = value; tfd->strip_bytes[1] = next_value; } else tfd->strip_bytes[0] = value; } }