Open gcode-importer opened 9 years ago
The norm ISO/IEC 15444-1 does define values for ENUMCS.
winfried
Reported by szukw000 on 2014-08-25 16:07:19
Reported by mayeut on 2014-10-09 18:11:01
I'm not sure if writing +1, 👍 or just cheering you guys on is appropriate, but I'd like to see this patch (or some version of it) be added to master. Having the possiblity to determine the resolution of an image would be really nice. :) If I can help you in any way, let me know.
Here is a copy the original patch:
diff --git a/src/lib/openjp2/jp2.c b/src/lib/openjp2/jp2.c
index 5c88c4d..f3d49c0 100644
--- a/src/lib/openjp2/jp2.c
+++ b/src/lib/openjp2/jp2.c
@@ -118,6 +118,16 @@ static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color);
*/
static OPJ_BYTE * opj_jp2_write_colr( opj_jp2_t *jp2,
OPJ_UINT32 * p_nb_bytes_written );
+/**
+ * Writes the Colour Specification box.
+ *
+ * @param jp2 jpeg2000 file codec.
+ * @param p_nb_bytes_written pointer to store the nb of bytes written by the function.
+ *
+ * @return the data being copied.
+*/
+static OPJ_BYTE * opj_jp2_write_res( opj_jp2_t *jp2,
+ OPJ_UINT32 * p_nb_bytes_written );
/**
* Writes a FTYP box - File type box
@@ -294,6 +304,21 @@ static OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
OPJ_UINT32 p_colr_header_size,
opj_event_mgr_t * p_manager );
+/**
+ * Reads the Color Specification box.
+ *
+ * @param p_colr_header_data pointer to actual data (already read from file)
+ * @param jp2 the jpeg2000 file codec.
+ * @param p_colr_header_size the size of the color header
+ * @param p_manager the user event manager.
+ *
+ * @return true if the bpc header is valid, fale else.
+*/
+static OPJ_BOOL opj_jp2_read_res( opj_jp2_t *jp2,
+ OPJ_BYTE * p_colr_header_data,
+ OPJ_UINT32 p_colr_header_size,
+ opj_event_mgr_t * p_manager );
+
/*@}*/
/*@}*/
@@ -397,6 +422,7 @@ const opj_jp2_header_handler_t jp2_img_header [] =
{
{JP2_IHDR,opj_jp2_read_ihdr},
{JP2_COLR,opj_jp2_read_colr},
+ {JP2_RES,opj_jp2_read_res},
{JP2_BPCC,opj_jp2_read_bpcc},
{JP2_PCLR,opj_jp2_read_pclr},
{JP2_CMAP,opj_jp2_read_cmap},
@@ -749,6 +775,106 @@ OPJ_BYTE * opj_jp2_write_colr( opj_jp2_t *jp2,
return l_colr_data;
}
+void opj_res (OPJ_FLOAT64 res, OPJ_UINT32 * rcn, OPJ_UINT32 *rcd) {
+ const int NUMFRACS = 30;
+ int i;
+
+ OPJ_UINT32 numerator [NUMFRACS];
+ OPJ_UINT32 denominator [NUMFRACS];
+
+ OPJ_FLOAT64 d=0, d2=0, d3, d4 = -1;
+ OPJ_UINT32 maxNumerator, L2;
+ (*rcn) = (int)(res / 100);
+ (*rcd) = 1;
+ d = d2 = (res / 100);
+
+ maxNumerator = 0x0ffff;
+
+ numerator[0]=0; denominator[0]=1;
+ numerator[1]=1; denominator[1]=0;
+
+ for(i=2; i<NUMFRACS; ++i)
+ {
+ L2 = (OPJ_UINT32)(d2 + 0.5);
+ numerator[i]= L2 * numerator[i-1] + numerator[i-2];
+ denominator[i]= L2 *denominator[i-1] + denominator[i-2];
+
+ d3 = ((OPJ_FLOAT64)(numerator[i])) / ((OPJ_FLOAT64)(denominator[i]));
+
+ if(d3==d4) break;
+
+ if(abs (numerator[i]) > maxNumerator) break;
+
+ (*rcn) = abs (numerator[i]);
+ (*rcd) = abs (denominator[i]);
+
+ if(d3==d) break;
+
+ d4=d3;
+
+ d2 = 1/(d2-L2);
+ }
+}
+
+OPJ_BYTE * opj_jp2_write_res( opj_jp2_t *jp2,
+ OPJ_UINT32 * p_nb_bytes_written)
+{
+ OPJ_UINT32 l_res_size = 26, l_resc_size = 18;
+ OPJ_BYTE * l_res_data, * l_current_res_ptr;
+
+ OPJ_UINT32 rcn, rcd, rce = 2;
+ /* preconditions */
+ assert(jp2 != 00);
+ assert(p_nb_bytes_written != 00);
+
+ l_res_data = (OPJ_BYTE *) opj_malloc(l_res_size);
+ if (l_res_data == 00) {
+ return 00;
+ }
+
+ memset(l_res_data,0,l_res_size);
+
+ l_current_res_ptr = l_res_data;
+
+ opj_write_bytes(l_current_res_ptr,l_res_size,4); /* write box size */
+ l_current_res_ptr += 4;
+
+ opj_write_bytes(l_current_res_ptr,JP2_RES,4); /* RES */
+ l_current_res_ptr += 4;
+
+ opj_write_bytes(l_current_res_ptr,l_resc_size,4); /* BPCC */
+ l_current_res_ptr += 4;
+
+ opj_write_bytes(l_current_res_ptr,JP2_RESC,4); /* BPCC */
+ l_current_res_ptr += 4;
+
+ opj_res (jp2->resdv, &rcn, &rcd);
+
+ opj_write_bytes(l_current_res_ptr, rcn, 2); /* VRcN */
+ l_current_res_ptr += 2;
+
+ opj_write_bytes(l_current_res_ptr, rcn, 2); /* VRcD */
+ l_current_res_ptr += 2;
+
+ opj_res (jp2->resdh, &rcn, &rcd);
+
+ opj_write_bytes(l_current_res_ptr, rcn, 2); /* HRcN */
+ l_current_res_ptr += 2;
+
+ opj_write_bytes(l_current_res_ptr, rcn, 2); /* HRcD */
+ l_current_res_ptr += 2;
+
+ opj_write_bytes(l_current_res_ptr, rce, 1); /* VRcE */
+ l_current_res_ptr += 1;
+
+ opj_write_bytes(l_current_res_ptr, rce, 1); /* HRcE */
+ l_current_res_ptr += 1;
+
+ *p_nb_bytes_written = l_res_size;
+
+ return l_res_data;
+}
+
void opj_jp2_free_pclr(opj_jp2_color_t *color)
{
opj_free(color->jp2_pclr->channel_sign);
@@ -1282,6 +1408,57 @@ OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
return OPJ_TRUE;
}
+OPJ_BOOL opj_jp2_read_res( opj_jp2_t *jp2,
+ OPJ_BYTE * p_res_header_data,
+ OPJ_UINT32 p_res_header_size,
+ opj_event_mgr_t * p_manager)
+{
+ OPJ_UINT32 size, type;
+ OPJ_UINT32 vrcn, vrcd, hrcn, hrcd, vrce, hrce;
+
+ /* preconditions */
+ assert(jp2 != 00);
+ assert(p_res_header_data != 00);
+ assert(p_manager != 00);
+
+ while (p_res_header_size >= 18) {
+ opj_read_bytes(p_res_header_data,&size ,4);
+ p_res_header_data += 4;
+
+ opj_read_bytes(p_res_header_data,&type ,4);
+ p_res_header_data += 4;
+
+ opj_read_bytes(p_res_header_data,&vrcn,2);
+ p_res_header_data += 2;
+
+ opj_read_bytes(p_res_header_data,&vrcd,2);
+ p_res_header_data += 2;
+
+ opj_read_bytes(p_res_header_data,&hrcn,2);
+ p_res_header_data += 2;
+
+ opj_read_bytes(p_res_header_data,&hrcd,2);
+ p_res_header_data += 2;
+
+ opj_read_bytes(p_res_header_data,&vrce,1);
+ ++p_res_header_data;
+
+ opj_read_bytes(p_res_header_data,&hrce,1);
+ ++p_res_header_data;
+
+ jp2->resdh = (OPJ_FLOAT64)(hrcn) / (OPJ_FLOAT64)(hrcd) * pow(10, hrce);
+ jp2->resdv = (OPJ_FLOAT64)(vrcn) / (OPJ_FLOAT64)(vrcd) * pow(10, vrce);
+
+ if ( JP2_RESD == type)
+ return OPJ_TRUE;
+
+ p_res_header_size -= size;
+ }
+
+ return OPJ_TRUE;
+}/* jp2_read_res() */
+
+
OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
opj_stream_private_t *p_stream,
opj_image_t* p_image,
@@ -1341,7 +1518,7 @@ OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
opj_event_mgr_t * p_manager
)
{
- opj_jp2_img_header_writer_handler_t l_writers [3];
+ opj_jp2_img_header_writer_handler_t l_writers [4];
opj_jp2_img_header_writer_handler_t * l_current_writer;
OPJ_INT32 i, l_nb_pass;
@@ -1359,16 +1536,19 @@ OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
memset(l_writers,0,sizeof(l_writers));
+
if (jp2->bpc == 255) {
- l_nb_pass = 3;
+ l_nb_pass = 4;
l_writers[0].handler = opj_jp2_write_ihdr;
l_writers[1].handler = opj_jp2_write_bpcc;
l_writers[2].handler = opj_jp2_write_colr;
+ l_writers[3].handler = opj_jp2_write_res;
}
else {
- l_nb_pass = 2;
+ l_nb_pass = 3;
l_writers[0].handler = opj_jp2_write_ihdr;
l_writers[1].handler = opj_jp2_write_colr;
+ l_writers[2].handler = opj_jp2_write_res;
}
/* write box header */
diff --git a/src/lib/openjp2/jp2.h b/src/lib/openjp2/jp2.h
index c11d2f3..6b43008 100644
--- a/src/lib/openjp2/jp2.h
+++ b/src/lib/openjp2/jp2.h
@@ -60,6 +60,9 @@
#define JP2_BPCC 0x62706363 /**< Bits per component box */
#define JP2_JP2 0x6a703220 /**< File type fields */
+#define JP2_RES 0x72657320 /**< Resolution box (super-box) */
+#define JP2_RESC 0x72657363 /**< File type fields */
+#define JP2_RESD 0x72657364 /**< File type fields */
/* For the future */
/* #define JP2_RES 0x72657320 */ /**< Resolution box (super-box) */
/* #define JP2_JP2I 0x6a703269 */ /**< Intellectual property box */
@@ -181,6 +184,8 @@ typedef struct opj_jp2
OPJ_UINT32 numcl;
OPJ_UINT32 *cl;
opj_jp2_comps_t *comps;
+ OPJ_FLOAT64 resdh;
+ OPJ_FLOAT64 resdv;
/* FIXME: The following two variables are used to save offset
as we write out a JP2 file to disk. This mecanism is not flexible
as codec writers will need to extand those fields as new part
diff --git a/src/lib/openjp2/openjpeg.h b/src/lib/openjp2/openjpeg.h
index e4b410e..840e0e8 100644
--- a/src/lib/openjp2/openjpeg.h
+++ b/src/lib/openjp2/openjpeg.h
@@ -701,6 +701,10 @@ typedef struct opj_image {
OPJ_BYTE *icc_profile_buf;
/** size of ICC profile */
OPJ_UINT32 icc_profile_len;
+ /** resolution display vertical */
+ OPJ_FLOAT64 resdv;
+ /** resolution display horizontal */
+ OPJ_FLOAT64 resdh;
} opj_image_t;
This is also included in the grok fork. What's the stance on backporting features from grok?
I'd really like so see support for JP2_RES
and JP2_COLR
in the mainline library. Both features are implemented in grok, and from what I can tell backporting them shouldn't be all too difficult.
If it's okay, I'd love to give this a try.
If it's okay, I'd love to give this a try.
This isn't OK from a license point of view. Grok uses a more restrictive license, and its code cannot legally be backported to openjpeg.
Thanks for getting back so quickly, I wasn't aware of that!
Basing a PR on @leguilc's code would be fine, though, right? Given that he submitted his patch for the openjpeg
project, can we safely assume that the copyright situation is clear?
can we safely assume that the copyright situation is clear?
yes
How time flies!! I completely forgotten about writing this code/patch ....
Originally reported on Google Code with ID 378
Reported by leguilc on 2014-08-20 15:25:33