* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/imgutils.h"
return temp;
}
-static uint16_t read10in32(const uint8_t **ptr, uint32_t * lbuf,
- int * n_datum, int is_big)
+static uint16_t read10in32_gray(const uint8_t **ptr, uint32_t *lbuf,
+ int *n_datum, int is_big, int shift)
+{
+ uint16_t temp;
+
+ if (*n_datum)
+ (*n_datum)--;
+ else {
+ *lbuf = read32(ptr, is_big);
+ *n_datum = 2;
+ }
+
+ temp = *lbuf >> shift & 0x3FF;
+ *lbuf = *lbuf >> 10;
+
+ return temp;
+}
+
+static uint16_t read10in32(const uint8_t **ptr, uint32_t *lbuf,
+ int *n_datum, int is_big, int shift)
{
if (*n_datum)
(*n_datum)--;
*n_datum = 2;
}
- *lbuf = (*lbuf << 10) | (*lbuf >> 22);
+ *lbuf = *lbuf << 10 | *lbuf >> shift & 0x3FFFFF;
return *lbuf & 0x3FF;
}
-static uint16_t read12in32(const uint8_t **ptr, uint32_t * lbuf,
- int * n_datum, int is_big)
+static uint16_t read12in32(const uint8_t **ptr, uint32_t *lbuf,
+ int *n_datum, int is_big)
{
if (*n_datum)
(*n_datum)--;
int buf_size = avpkt->size;
AVFrame *const p = data;
uint8_t *ptr[AV_NUM_DATA_POINTERS];
+ uint32_t header_version, version = 0;
+ char creator[101];
+ char input_device[33];
unsigned int offset;
int magic_num, endian;
return AVERROR_INVALIDDATA;
}
+ header_version = read32(&buf, 0);
+ if (header_version == MKTAG('V','1','.','0'))
+ version = 1;
+ if (header_version == MKTAG('V','2','.','0'))
+ version = 2;
+ if (!version)
+ av_log(avctx, AV_LOG_WARNING, "Unknown header format version %s.\n",
+ av_fourcc2str(header_version));
+
// Check encryption
buf = avpkt->data + 660;
ret = read32(&buf, endian);
packing = read16(&buf, endian);
encoding = read16(&buf, endian);
- if (packing > 1) {
- avpriv_report_missing_feature(avctx, "Packing %d", packing);
- return AVERROR_PATCHWELCOME;
- }
if (encoding) {
avpriv_report_missing_feature(avctx, "Encoding %d", encoding);
return AVERROR_PATCHWELCOME;
stride = (avctx->width * elements + 2) / 3 * 4;
break;
case 12:
- if (!packing) {
- int tested = 0;
- if (descriptor == 50 && endian && (avctx->width%8) == 0) { // Little endian and widths not a multiple of 8 need tests
- tested = 1;
- }
- if (!tested) {
- av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
- return -1;
- }
- }
stride = avctx->width * elements;
if (packing) {
stride *= 2;
case 51121:
avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
break;
+ case 6100:
+ case 6101:
+ avctx->pix_fmt = AV_PIX_FMT_GRAY10;
+ break;
case 6161:
avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
break;
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret;
+ av_strlcpy(creator, avpkt->data + 160, 100);
+ creator[100] = '\0';
+ av_dict_set(&p->metadata, "Creator", creator, 0);
+
+ av_strlcpy(input_device, avpkt->data + 1556, 32);
+ input_device[32] = '\0';
+ av_dict_set(&p->metadata, "Input Device", input_device, 0);
+
// Move pointer to offset from start of file
buf = avpkt->data + offset;
(uint16_t*)ptr[1],
(uint16_t*)ptr[2],
(uint16_t*)ptr[3]};
+ int shift = elements > 1 ? packing == 1 ? 22 : 20 : packing == 1 ? 2 : 0;
for (y = 0; y < avctx->width; y++) {
- *dst[2]++ = read10in32(&buf, &rgbBuffer,
- &n_datum, endian);
- *dst[0]++ = read10in32(&buf, &rgbBuffer,
- &n_datum, endian);
- *dst[1]++ = read10in32(&buf, &rgbBuffer,
- &n_datum, endian);
+ if (elements >= 3)
+ *dst[2]++ = read10in32(&buf, &rgbBuffer,
+ &n_datum, endian, shift);
+ if (elements == 1)
+ *dst[0]++ = read10in32_gray(&buf, &rgbBuffer,
+ &n_datum, endian, shift);
+ else
+ *dst[0]++ = read10in32(&buf, &rgbBuffer,
+ &n_datum, endian, shift);
+ if (elements >= 2)
+ *dst[1]++ = read10in32(&buf, &rgbBuffer,
+ &n_datum, endian, shift);
if (elements == 4)
*dst[3]++ =
read10in32(&buf, &rgbBuffer,
- &n_datum, endian);
+ &n_datum, endian, shift);
}
- n_datum = 0;
+ if (memcmp(input_device, "Scanity", 7))
+ n_datum = 0;
for (i = 0; i < elements; i++)
ptr[i] += p->linesize[i];
}
(uint16_t*)ptr[1],
(uint16_t*)ptr[2],
(uint16_t*)ptr[3]};
+ int shift = packing == 1 ? 4 : 0;
for (y = 0; y < avctx->width; y++) {
if (packing) {
- if (elements >= 3)
- *dst[2]++ = read16(&buf, endian) >> 4;
- *dst[0] = read16(&buf, endian) >> 4;
- dst[0]++;
- if (elements >= 2)
- *dst[1]++ = read16(&buf, endian) >> 4;
- if (elements == 4)
- *dst[3]++ = read16(&buf, endian) >> 4;
+ if (elements >= 3)
+ *dst[2]++ = read16(&buf, endian) >> shift & 0xFFF;
+ *dst[0]++ = read16(&buf, endian) >> shift & 0xFFF;
+ if (elements >= 2)
+ *dst[1]++ = read16(&buf, endian) >> shift & 0xFFF;
+ if (elements == 4)
+ *dst[3]++ = read16(&buf, endian) >> shift & 0xFFF;
} else {
- *dst[2]++ = read12in32(&buf, &rgbBuffer,
- &n_datum, endian);
+ if (elements >= 3)
+ *dst[2]++ = read12in32(&buf, &rgbBuffer,
+ &n_datum, endian);
*dst[0]++ = read12in32(&buf, &rgbBuffer,
&n_datum, endian);
- *dst[1]++ = read12in32(&buf, &rgbBuffer,
- &n_datum, endian);
+ if (elements >= 2)
+ *dst[1]++ = read12in32(&buf, &rgbBuffer,
+ &n_datum, endian);
if (elements == 4)
*dst[3]++ = read12in32(&buf, &rgbBuffer,
&n_datum, endian);
}
}
+ n_datum = 0;
for (i = 0; i < elements; i++)
ptr[i] += p->linesize[i];
// Jump to next aligned position