1 #include "jpgconverter.h"
2 
3 #include <QFile>
4 #include <QDataStream>
5 //=============================================================================
6 //=============================================================================
7 
JpgConverter()8 JpgConverter::JpgConverter() {}
~JpgConverter()9 JpgConverter::~JpgConverter() {}
10 
11 #ifdef WITH_CANON
12 
setStream(EdsStreamRef stream)13 void JpgConverter::setStream(EdsStreamRef stream) { m_stream = stream; }
14 
convertFromJpg()15 void JpgConverter::convertFromJpg() {
16 #ifdef MACOSX
17   UInt64 mySize = 0;
18 #else
19   unsigned __int64 mySize = 0;
20 #endif
21   unsigned char* data = NULL;
22   EdsError err        = EdsGetPointer(m_stream, (EdsVoid**)&data);
23   err                 = EdsGetLength(m_stream, &mySize);
24 
25   int width, height, pixelFormat;
26   int inSubsamp, inColorspace;
27   tjhandle tjInstance   = NULL;
28   unsigned char* imgBuf = NULL;
29   tjInstance            = tjInitDecompress();
30   tjDecompressHeader3(tjInstance, data, mySize, &width, &height, &inSubsamp,
31                       &inColorspace);
32 
33   if (width < 0 || height < 0) {
34     emit(imageReady(false));
35     return;
36   }
37 
38   pixelFormat = TJPF_BGRX;
39   imgBuf = (unsigned char*)tjAlloc(width * height * tjPixelSize[pixelFormat]);
40   int flags = 0;
41   flags |= TJFLAG_BOTTOMUP;
42 
43   int factorsNum;
44   tjscalingfactor scalingFactor = {1, 1};
45   tjscalingfactor* factor       = tjGetScalingFactors(&factorsNum);
46   int i                         = 0;
47   int tempWidth, tempHeight;
48   while (i < factorsNum) {
49     scalingFactor = factor[i];
50     i++;
51     tempWidth  = TJSCALED(width, scalingFactor);
52     tempHeight = TJSCALED(height, scalingFactor);
53   }
54   tjDecompress2(tjInstance, data, mySize, imgBuf, width,
55                 width * tjPixelSize[pixelFormat], height, pixelFormat, flags);
56 
57   m_finalImage = TRaster32P(width, height);
58   m_finalImage->lock();
59   uchar* rawData = m_finalImage->getRawData();
60   memcpy(rawData, imgBuf, width * height * tjPixelSize[pixelFormat]);
61   m_finalImage->unlock();
62 
63   tjFree(imgBuf);
64   imgBuf = NULL;
65   tjDestroy(tjInstance);
66   tjInstance = NULL;
67 
68   if (m_stream != NULL) {
69     EdsRelease(m_stream);
70     m_stream = NULL;
71   }
72   data = NULL;
73   emit(imageReady(true));
74 }
75 
run()76 void JpgConverter::run() { convertFromJpg(); }
77 
78 #endif
79 
80 //-----------------------------------------------------------------------------
81 
saveJpg(TRaster32P image,TFilePath path)82 void JpgConverter::saveJpg(TRaster32P image, TFilePath path) {
83   unsigned char* jpegBuf = NULL; /* Dynamically allocate the JPEG buffer */
84   unsigned long jpegSize = 0;
85   int pixelFormat        = TJPF_BGRX;
86   int outQual            = 95;
87   int subSamp            = TJSAMP_411;
88   bool success           = false;
89   tjhandle tjInstance;
90 
91   int width  = image->getLx();
92   int height = image->getLy();
93   int flags  = 0;
94   flags |= TJFLAG_BOTTOMUP;
95 
96   image->lock();
97   uchar* rawData = image->getRawData();
98   if ((tjInstance = tjInitCompress()) != NULL) {
99     if (tjCompress2(tjInstance, rawData, width, 0, height, pixelFormat,
100                     &jpegBuf, &jpegSize, subSamp, outQual, flags) >= 0) {
101       success = true;
102     }
103   }
104   image->unlock();
105   tjDestroy(tjInstance);
106   tjInstance = NULL;
107 
108   if (success) {
109     /* Write the JPEG image to disk. */
110     QFile fullImage(path.getQString());
111     fullImage.open(QIODevice::WriteOnly);
112     QDataStream dataStream(&fullImage);
113     dataStream.writeRawData((const char*)jpegBuf, jpegSize);
114     fullImage.close();
115   }
116   tjFree(jpegBuf);
117   jpegBuf = NULL;
118 }
119 
120 //-----------------------------------------------------------------------------
121 
loadJpg(TFilePath path,TRaster32P & image)122 bool JpgConverter::loadJpg(TFilePath path, TRaster32P& image) {
123   long size;
124   int inSubsamp, inColorspace, width, height;
125   unsigned long jpegSize;
126   unsigned char* jpegBuf;
127   FILE* jpegFile;
128   QString qPath      = path.getQString();
129   QByteArray ba      = qPath.toLocal8Bit();
130   const char* c_path = ba.data();
131   bool success       = true;
132   tjhandle tjInstance;
133 
134   /* Read the JPEG file into memory. */
135   if ((jpegFile = fopen(c_path, "rb")) == NULL) success = false;
136   if (success && fseek(jpegFile, 0, SEEK_END) < 0 ||
137       ((size = ftell(jpegFile)) < 0) || fseek(jpegFile, 0, SEEK_SET) < 0)
138     success = false;
139   if (success && size == 0) success = false;
140   jpegSize = (unsigned long)size;
141   if (success && (jpegBuf = (unsigned char*)tjAlloc(jpegSize)) == NULL)
142     success = false;
143   if (success && fread(jpegBuf, jpegSize, 1, jpegFile) < 1) success = false;
144   fclose(jpegFile);
145   jpegFile = NULL;
146 
147   if (success && (tjInstance = tjInitDecompress()) == NULL) success = false;
148 
149   if (success && tjDecompressHeader3(tjInstance, jpegBuf, jpegSize, &width,
150                                      &height, &inSubsamp, &inColorspace) < 0)
151     success = false;
152 
153   int pixelFormat       = TJPF_BGRX;
154   unsigned char* imgBuf = NULL;
155   if (success &&
156       (imgBuf = tjAlloc(width * height * tjPixelSize[pixelFormat])) == NULL)
157     success = false;
158 
159   int flags = 0;
160   flags |= TJFLAG_BOTTOMUP;
161   if (success && tjDecompress2(tjInstance, jpegBuf, jpegSize, imgBuf, width, 0,
162                                height, pixelFormat, flags) < 0)
163     success = false;
164   tjFree(jpegBuf);
165   jpegBuf = NULL;
166   tjDestroy(tjInstance);
167   tjInstance = NULL;
168 
169   image = TRaster32P(width, height);
170   image->lock();
171   uchar* rawData = image->getRawData();
172   memcpy(rawData, imgBuf, width * height * tjPixelSize[pixelFormat]);
173   image->unlock();
174 
175   tjFree(imgBuf);
176   imgBuf = NULL;
177 
178   return success;
179 }