]> Creatis software - gdcm.git/blob - src/gdcmJpeg2000.cxx
ENH: Remove ref to jasper, add OpenJPEG implementation
[gdcm.git] / src / gdcmJpeg2000.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmJpeg2000.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/10/24 15:36:33 $
7   Version:   $Revision: 1.29 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 #include "gdcmFileHelper.h"
19 #include "gdcmDebug.h"
20
21 #include <iostream>
22 #include <fstream>
23 //#include <jasper/jasper.h>
24 extern "C" {
25 #include <openjpeg.h>
26 }
27
28 namespace gdcm 
29 {
30 //-----------------------------------------------------------------------------
31  /**
32  * \brief   routine for JPEG decompression 
33  * @param raw raw
34  * @param inputdata inputdata
35  * @param inputlength inputlength 
36  * @return 1 on success, 0 on error
37  */
38
39 bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength)
40 {
41   j2k_image_t img;
42   j2k_cp_t cp;
43   //jp2_struct_t *jp2_struct=NULL;
44
45   // default blindly copied
46   cp.layer=0;
47   cp.reduce=0;
48   cp.decod_format=-1;
49   cp.cod_format=-1;
50
51   cp.cod_format=J2K_CFMT;
52   cp.decod_format = PGX_DFMT;
53   int len = inputlength;
54   unsigned char *src = (unsigned char*)inputdata;
55
56     if (!j2k_decode(src, len, &img, &cp)) {
57       fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
58       return false;
59     }
60
61
62     /************** PGX *****************/
63     //char *data8 = (char*)raw;
64     //uint16_t *data8 = (uint16_t*)raw;
65    for (int compno = 0; compno < img.numcomps; compno++) {
66       j2k_comp_t *comp = &img.comps[compno];
67       int nbytes = 0;
68  
69       // w = int_ceildiv(img.x1 - img.x0, comp->dx);
70       // wr = int_ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), comp->dx);
71       int w = img.comps[compno].w;
72       int wr = int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor);
73       std::cerr << "wr=" << wr << std::endl;
74       
75       // h = int_ceildiv(img.y1 - img.y0, comp->dy);
76       // hr = int_ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), comp->dy);
77       int h = img.comps[compno].h;
78       int hr = int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor);
79       std::cerr << "hr=" << hr << std::endl;
80       
81       //fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+',
82       //  comp->prec, wr, hr);
83
84       if (comp->prec <= 8)
85         {
86         nbytes = 1;
87         uint8_t *data8 = (uint8_t*)raw;
88         for (int i = 0; i < wr * hr; i++) 
89           {
90           int v = img.comps[compno].data[i / wr * w + i % wr];
91           *data8++ = (uint8_t)v;
92           }
93         }
94       else if (comp->prec <= 16)
95         {
96         nbytes = 2;
97         uint16_t *data16 = (uint16_t*)raw;
98         for (int i = 0; i < wr * hr; i++) 
99           {
100           int v = img.comps[compno].data[i / wr * w + i % wr];
101           *data16++ = (uint16_t)v;
102           }
103         }
104       else
105         {
106         nbytes = 4;
107         uint32_t *data32 = (uint32_t*)raw;
108         for (int i = 0; i < wr * hr; i++) 
109           {
110           int v = img.comps[compno].data[i / wr * w + i % wr];
111           *data32++ = (uint32_t)v;
112           }
113         }
114 //      for (int i = 0; i < wr * hr; i++) 
115 //        {
116 //        //std::cout << "i:" << i << '\n';
117 //        int v = img.comps[compno].data[i / wr * w + i % wr];
118 //        //for (int j = nbytes - 1; j >= 0; j--) 
119 //        for (int j = 0; j < nbytes-1 ; j++) 
120 //          {
121 //          char byte = (char) (v >> (j * 8));
122 //          //fwrite(&byte, 1, 1, fdest);
123 //          *data8++ = byte;
124 //        }
125 //        //*data8++ = (uint16_t)v;
126 //      }
127       free(img.comps[compno].data);
128 //      fclose(fdest);
129     /************** END PGX *****************/
130    }
131
132
133   // Free remaining structures
134   //--------------------------
135   delete[] inputdata;
136   j2k_dec_release();
137
138   return true;
139 }
140
141 #if 0
142 bool gdcm_read_JASPER_file (void* raw, char *inputdata, size_t inputlength)
143 {
144 #if 0
145   std::cerr << "Inputlenght=" << inputlength << std::endl;
146   std::ofstream out("/tmp/jpeg2000.jpc", std::ios::binary);
147   out.write((char*)inputdata,inputlength);
148   out.close();
149 #endif
150   jas_init(); //important...
151   jas_stream_t *jasStream = 
152     jas_stream_memopen((char *)inputdata, inputlength);
153     
154   int fmtid;
155   if ((fmtid = jas_image_getfmt(jasStream)) < 0) 
156     {
157     gdcmErrorMacro("unknown image format");
158     return false;
159     }
160
161   // Decode the image. 
162   jas_image_t *jasImage /* = NULL*/; // Useless assignation
163   if (!(jasImage = jas_image_decode(jasStream, fmtid, 0))) 
164     {
165     gdcmErrorMacro("cannot decode image");
166     return false;
167     }
168
169   // close the stream. 
170   jas_stream_close(jasStream);
171   int numcmpts = jas_image_numcmpts(jasImage);
172   int width = jas_image_cmptwidth(jasImage, 0);
173   int height = jas_image_cmptheight(jasImage, 0);
174   int prec = jas_image_cmptprec(jasImage, 0);
175   int i, j, k;
176
177   // The following should serioulsy be rewritten I cannot believe we need to
178   // do a per pixel decompression, there should be a way to read a full
179   // scanline...
180   if (prec == 8)
181     {
182     uint8_t *data8 = (uint8_t*)raw;
183     for ( i = 0; i < height; i++)
184       for ( j = 0; j < width; j++)
185         for ( k= 0; k < numcmpts; k++)
186           *data8++ = (uint8_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
187     }
188   else if (prec <= 16)
189     {
190     uint16_t *data16 = (uint16_t*)raw;
191     for ( i = 0; i < height; i++) 
192       for ( j = 0; j < width; j++) 
193         for ( k= 0; k < numcmpts; k++)
194           *data16++ = (uint16_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
195     }
196   else if (prec <= 32)
197     {
198     uint32_t *data32 = (uint32_t*)raw;
199     for ( i = 0; i < height; i++) 
200       for ( j = 0; j < width; j++) 
201         for ( k= 0; k < numcmpts; k++)
202           *data32++ = (uint32_t)(jas_image_readcmptsample(jasImage, k, j ,i ));
203     }
204
205   jas_image_destroy(jasImage);
206   jas_image_clearfmts();
207
208   //FIXME
209   //delete the jpeg temp buffer
210 #if 0
211   std::ofstream rawout("/tmp/jpeg2000.raw");
212   rawout.write((char*)raw,height*width*numcmpts*((prec+4)/8));
213   rawout.close();
214 #endif
215   delete[] inputdata;
216
217   return true;
218 }
219 #endif
220
221 //-----------------------------------------------------------------------------
222 } // end namespace gdcm
223