native.c (2748B)
1 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <stdarg.h> 5 #include <string.h> 6 #include <unistd.h> 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <vxa/vxa.h> 11 #include <vxa/codec.h> 12 13 #include "jasper/jasper.h" 14 #include "native.h" 15 16 17 #define BUFSIZE (64*1024) 18 19 char vxacodec_name[] = "jp2"; 20 21 22 // Defined in djp2-bin.c, generated from djp2 by bin2c.pl 23 extern const uint8_t vxa_djp2_data[]; 24 extern const int vxa_djp2_length; 25 26 27 static void init() 28 { 29 static int inited; 30 if (inited) 31 return; 32 inited = 1; 33 34 int fmtid = 0; 35 jas_image_fmtops_t fmtops; 36 37 fmtops.decode = jp2_decode; 38 fmtops.encode = NULL; 39 fmtops.validate = jp2_validate; 40 jas_image_addfmt(fmtid, "jp2", "jp2", 41 "JPEG-2000 JP2 File Format Syntax (ISO/IEC 15444-1)", &fmtops); 42 ++fmtid; 43 44 fmtops.decode = NULL; 45 fmtops.encode = bmp_encode; 46 fmtops.validate = NULL; 47 jas_image_addfmt(fmtid, "bmp", "bmp", 48 "Microsoft Bitmap (BMP)", &fmtops); 49 ++fmtid; 50 } 51 52 int vxacodec_init(struct vxacodec *c, struct vxaio *io) 53 { 54 c->decoder = vxa_djp2_data; 55 c->decodersize = vxa_djp2_length; 56 } 57 58 int vxacodec_encode(vxacodec *c, vxaio *io) 59 { 60 return vxa_error(io, VXA_RC_WRONG_FORMAT, 61 "JPEG 2000 codec does not yet support compression"); 62 } 63 64 int vxacodec_decode(vxacodec *c, vxaio *io) 65 { 66 init(); 67 68 if (io->method != VXA_M_JP2) 69 return vxa_error(io, VXA_RC_WRONG_FORMAT, 70 "jp2: unsupported method code %08x", 71 io->method); 72 73 jas_stream_t *in = jas_stream_vxaopen(io, JAS_STREAM_READ); 74 if (in == NULL) 75 return vxa_error(io, VXA_RC_NO_MEMORY, "out of memory"); 76 77 jas_stream_t *out = jas_stream_vxaopen(io, JAS_STREAM_WRITE); 78 if (out == NULL) 79 return vxa_error(io, VXA_RC_NO_MEMORY, "out of memory"); 80 81 jas_image_t *image = jas_image_decode(in, 0, NULL); 82 if (image == NULL) 83 return vxa_error(io, VXA_RC_UNKNOWN, 84 "error decoding JP2 image"); 85 // XX can we be more specific? 86 87 int rc = jas_image_encode(image, out, 1, NULL); 88 if (rc != 0) 89 return vxa_error(io, VXA_RC_UNKNOWN, 90 "error writing BMP image"); 91 // XX can we be more specific? 92 93 jas_stream_flush(out); 94 95 jas_stream_close(in); 96 jas_stream_close(out); 97 98 jas_image_destroy(image); 99 100 return VXA_RC_OK; 101 } 102 103 static uint8_t magic[] = { 104 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A, 105 0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70, 0x6A, 0x70, 0x32 }; 106 107 int vxacodec_recognize(vxacodec *c, vxaio *io, const void *header, size_t size) 108 { 109 assert(sizeof(magic) == 23); 110 if (size >= 23 && memcmp(header, magic, 23) == 0) { 111 io->method = VXA_M_JP2; 112 return vxa_error(io, VXA_RC_COMPRESSED, 113 "input already compressed in JP2 format"); 114 } 115 116 // Format not recognized, but we could try compressing it anyway... 117 return vxa_error(io, VXA_RC_WRONG_FORMAT, 118 "JP2 codec currently can't compress"); 119 } 120