Xmipp  v3.23.11-Nereus
rwJPEG.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: Joaquin Oton (joton@cnb.csic.es)
3  *
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "xmipp_image_base.h"
27 #include "jpeglib.h"
28 #include "xmipp_error.h"
29 #include "multidim_array_base.h"
30 #include "metadata_static.h"
31 
32 //#include <jpeglib.h>
33 
34 int ImageBase::readJPEG(size_t select_img)
35 {
36  struct jpeg_decompress_struct cinfo;
37  struct jpeg_error_mgr jerr;
38 
39  cinfo.err = jpeg_std_error(&jerr);
40  jpeg_create_decompress(&cinfo);
41 
42  jpeg_stdio_src(&cinfo, fimg);
43  jpeg_read_header(&cinfo, TRUE);
44 
53 
54  ArrayDim aDim;
55  aDim.xdim = cinfo.image_width;
56  aDim.ydim = cinfo.image_height;
57  aDim.zdim = 1;
58  aDim.ndim = 1;
59 
60  setDimensions(aDim);
61 
62  replaceNsize = aDim.ndim;
63 
64  //Read header only
65  if (dataMode == HEADER || (dataMode == _HEADER_ALL )) // Stop reading if not necessary
66  {
67  jpeg_destroy_decompress(&cinfo);
68  return 0;
69  }
70 
71  /* As we cannot mmap a TIFF File, when this option is passed we are going to mmap
72  * the multidimarray of Image
73  */
74 
75  if (mmapOnRead)
76  {
77  mmapOnRead = false;
78  if (aDim.nzyxdim*gettypesize(DT_UChar) > tiff_map_min_size)
79  mdaBase->setMmap(true);
80  }
81 
82  // Allocate memory for image data (Assume xdim, ydim, zdim and ndim are already set
83  //if memory already allocated use it (no resize allowed)
85 
86  MD.clear();
87  for (size_t i = 0; i < aDim.ndim; i++)
88  MD.push_back(std::unique_ptr<MDRowVec>(new MDRowVec(MDL::emptyHeaderVec())));
89 
90  /* Start decompression jpeg here */
91  jpeg_start_decompress( &cinfo );
92 
93  /* allocate memory to hold the uncompressed image */
94  char * buffer = new char [aDim.xdim];
95  /* now actually read the jpeg into the raw buffer */
96  JSAMPROW row_pointer[1];
97  row_pointer[0] = new unsigned char [aDim.xdim*cinfo.num_components];
98  /* read one scan line at a time */
99  while( cinfo.output_scanline < cinfo.image_height )
100  {
101  jpeg_read_scanlines( &cinfo, row_pointer, 1 );
102  for(size_t i=0; i<cinfo.image_width;i++)
103  buffer[i] = row_pointer[0][i*cinfo.num_components];
104  setPage2T((cinfo.output_scanline - 1)*cinfo.image_width, buffer, DT_UChar, aDim.xdim);
105  }
106  /* wrap up decompression, destroy objects, free pointers and close open files */
107  jpeg_finish_decompress( &cinfo );
108  jpeg_destroy_decompress( &cinfo );
109  delete[] row_pointer[0];
110 
111  return 0;
112 }
113 
114 /* setup the buffer but we did that in the main function */
115 void init_buffer(jpeg_compress_struct* cinfo)
116 {}
117 
118 /* what to do when the buffer is full; this should almost never
119  * happen since we allocated our buffer to be big to start with
120  */
121 boolean empty_buffer(jpeg_compress_struct* cinfo)
122 {
123  return TRUE;
124 }
125 
126 /* finalize the buffer and do any cleanup stuff */
127 void term_buffer(jpeg_compress_struct* cinfo)
128 {}
129 
130 int ImageBase::writeJPEG(size_t select_img, bool isStack, int mode, String bitDepth, CastWriteMode castMode)
131 {
132  if (isComplexT())
133  {
134  REPORT_ERROR(ERR_TYPE_INCORRECT,"rwJPEG: Complex images are not supported by JPEG format.");
135  return 0;
136  }
137 
138  ArrayDim aDim;
139  mdaBase->getDimensions(aDim);
140 
141  // Volumes are not supported
142  if (aDim.zdim > 1)
143  REPORT_ERROR(ERR_MULTIDIM_DIM, "rwJPEG: volumes are not supported.");
144 
145  //Selection of output datatype
146  DataType myTypeID = myT();
147 
148  if (mmapOnWrite)
149  {
150  /* As we cannot mmap a JPEG File, when this option is passed we are going to mmap
151  * the multidimarray of Image
152  */
153  mmapOnWrite = false;
154  dataMode = DATA;
155  MDMainHeader.setValue(MDL_DATATYPE,(int) myTypeID);
156 
157  if (aDim.nzyxdim*gettypesize(myTypeID) > tiff_map_min_size)
158  mdaBase->setMmap(true);
159 
160  // Allocate memory for image data (Assume xdim, ydim, zdim and ndim are already set
161  //if memory already allocated use it (no resize allowed)
162 
164 
165  return 0;
166  }
167 
168  jpeg_compress_struct cinfo;
169  jpeg_error_mgr jerr;
170 
171  // struct jpeg_destination_mgr dmgr;
172  //
173  // /* create our in-memory output buffer to hold the jpeg */
174  // JOCTET * out_buffer = new JOCTET[aDim.xdim * aDim.ydim];
175  //
176  // /* here is the magic */
177  // dmgr.init_destination = init_buffer;
178  // dmgr.empty_output_buffer = empty_buffer;
179  // dmgr.term_destination = term_buffer;
180  // dmgr.next_output_byte = out_buffer;
181  // dmgr.free_in_buffer = aDim.xdim * aDim.ydim;
182 
183  cinfo.err = jpeg_std_error(&jerr);
184  jpeg_create_compress(&cinfo);
185 
186  jpeg_stdio_dest(&cinfo, fimg);
187 
188  /* Set JPEG image properties */
189  cinfo.image_width = aDim.xdim; /* image width and height, in pixels */
190  cinfo.image_height = aDim.ydim;
191  cinfo.input_components = 1; /* # of color components per pixel */
192  cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
193 
194  jpeg_set_defaults(&cinfo);
195 
196  jpeg_start_compress(&cinfo, TRUE);
197 
198  JSAMPROW row_pointer[1]; /* pointer to a single row */
199  row_pointer[0] = new unsigned char [aDim.xdim];
200  char * buffer = (char*) row_pointer[0];
201  double min0, max0;
202  mdaBase->computeDoubleMinMaxRange(min0, max0, 0, aDim.xdim*aDim.ydim);
203 
204 
205  while (cinfo.next_scanline < cinfo.image_height)
206  {
207  getCastConvertPageFromT((cinfo.next_scanline)*cinfo.image_width, buffer,
208  DT_UChar, cinfo.image_width, min0, max0, castMode);
209 
210  jpeg_write_scanlines(&cinfo, row_pointer, 1);
211  }
212 
213  jpeg_finish_compress(&cinfo);
214  jpeg_destroy_compress(&cinfo);
215  delete[] row_pointer[0];
216 
217  // fwrite(out_buffer, cinfo.dest->next_output_byte - out_buffer,1 ,fimg);
218 
219  return(0);
220 }
tsne coefficients in 2D
sampling rate in A/pixel (double)
size_t xdim
sampling rate in A/pixel (double)
DataMode dataMode
sampling rate in A/pixel (double)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
virtual void setPage2T(size_t offset, char *page, DataType datatype, size_t pageSize)=0
Maximum value (double)
virtual void coreAllocateReuse()=0
HBITMAP buffer
Definition: svm-toy.cpp:37
void setValue(const MDObject &object) override
std::vector< std::unique_ptr< MDRow > > MD
boolean empty_buffer(jpeg_compress_struct *cinfo)
Definition: rwJPEG.cpp:121
if read from file original image datatype, this is an struct defined in image
#define i
Minimum value (double)
virtual void computeDoubleMinMaxRange(double &minval, double &maxval, size_t offset, size_t size) const =0
size_t nzyxdim
size_t zdim
const size_t tiff_map_min_size
void setMmap(bool mmap)
virtual void setDimensions(int Xdim, int Ydim, int Zdim, size_t Ndim)=0
virtual bool isComplexT() const =0
static MDRowVec emptyHeaderVec()
DataType
void mode
void term_buffer(jpeg_compress_struct *cinfo)
Definition: rwJPEG.cpp:127
int readJPEG(size_t select_img)
Definition: rwJPEG.cpp:34
MDRowVec MDMainHeader
size_t ndim
void init_buffer(jpeg_compress_struct *cinfo)
Definition: rwJPEG.cpp:115
std::string String
Definition: xmipp_strings.h:34
virtual void getCastConvertPageFromT(size_t offset, char *page, DataType datatype, size_t pageSize, double min0, double max0, CastWriteMode castMode=CW_CONVERT) const =0
#define TRUE
Definition: defines.h:25
size_t ydim
average value (double)
Incorrect MultidimArray dimensions.
Definition: xmipp_error.h:173
CastWriteMode
virtual DataType myT() const =0
Incorrect type received.
Definition: xmipp_error.h:190
size_t replaceNsize
MultidimArrayBase * mdaBase
int writeJPEG(size_t select_img, bool isStack=false, int mode=WRITE_OVERWRITE, String bitDepth="", CastWriteMode castMode=CW_CONVERT)
Definition: rwJPEG.cpp:130
size_t gettypesize(DataType type)
Returns memory size of datatype.
void getDimensions(size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim) const