• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KImgIO

  • sources
  • kde-4.14
  • kdelibs
  • kimgio
hdr.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  Copyright (C) 2005 Christoph Hormann <chris_hormann@gmx.de>
3  Copyright (C) 2005 Ignacio CastaƱo <castanyo@yahoo.es>
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the Lesser GNU General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 */
10 
11 #include "hdr.h"
12 
13 #include <QtGui/QImage>
14 #include <QtCore/QDataStream>
15 
16 #include <kdebug.h>
17 
18 typedef Q_UINT8 uchar;
19 
20 namespace { // Private.
21 
22 #define MAXLINE 1024
23 #define MINELEN 8 // minimum scanline length for encoding
24 #define MAXELEN 0x7fff // maximum scanline length for encoding
25 
26  static inline uchar ClipToByte(float value)
27  {
28  if (value > 255.0f) return 255;
29  //else if (value < 0.0f) return 0; // we know value is positive.
30  return uchar(value);
31  }
32 
33  // read an old style line from the hdr image file
34  // if 'first' is true the first byte is already read
35  static bool Read_Old_Line (uchar * image, int width, QDataStream & s)
36  {
37  int rshift = 0;
38  int i;
39 
40  while (width > 0)
41  {
42  s >> image[0];
43  s >> image[1];
44  s >> image[2];
45  s >> image[3];
46 
47  if (s.atEnd()) return false;
48 
49  if ((image[0] == 1) && (image[1] == 1) && (image[2] == 1))
50  {
51  for (i = image[3] << rshift; i > 0; i--)
52  {
53  //memcpy(image, image-4, 4);
54  (uint &)image[0] = (uint &)image[0-4];
55  image += 4;
56  width--;
57  }
58  rshift += 8;
59  }
60  else
61  {
62  image += 4;
63  width--;
64  rshift = 0;
65  }
66  }
67  return true;
68  }
69 
70 
71  static void RGBE_To_QRgbLine(uchar * image, QRgb * scanline, int width)
72  {
73  for (int j = 0; j < width; j++)
74  {
75  // v = ldexp(1.0, int(image[3]) - 128);
76  float v;
77  int e = int(image[3]) - 128;
78  if( e > 0 )
79  {
80  v = float(1 << e);
81  }
82  else
83  {
84  v = 1.0f / float(1 << -e);
85  }
86 
87  scanline[j] = qRgb( ClipToByte(float(image[0]) * v),
88  ClipToByte(float(image[1]) * v),
89  ClipToByte(float(image[2]) * v) );
90 
91  image += 4;
92  }
93  }
94 
95  // Load the HDR image.
96  static bool LoadHDR( QDataStream & s, const int width, const int height, QImage & img )
97  {
98  uchar val, code;
99 
100  // Create dst image.
101  if( !img.create( width, height, 32 ) )
102  {
103  return false;
104  }
105 
106  QMemArray<uchar> image( width * 4 );
107 
108  for (int cline = 0; cline < height; cline++)
109  {
110  QRgb * scanline = (QRgb *) img.scanLine( cline );
111 
112  // determine scanline type
113  if ((width < MINELEN) || (MAXELEN < width))
114  {
115  Read_Old_Line(image.data(), width, s);
116  RGBE_To_QRgbLine(image.data(), scanline, width);
117  continue;
118  }
119 
120  s >> val;
121 
122  if (s.atEnd())
123  {
124  return true;
125  }
126 
127  if (val != 2)
128  {
129  s.device()->at( s.device()->at() - 1 );
130  Read_Old_Line(image.data(), width, s);
131  RGBE_To_QRgbLine(image.data(), scanline, width);
132  continue;
133  }
134 
135  s >> image[1];
136  s >> image[2];
137  s >> image[3];
138 
139  if (s.atEnd())
140  {
141  return true;
142  }
143 
144  if ((image[1] != 2) || (image[2] & 128))
145  {
146  image[0] = 2;
147  Read_Old_Line(image.data()+4, width-1, s);
148  RGBE_To_QRgbLine(image.data(), scanline, width);
149  continue;
150  }
151 
152  if ((image[2] << 8 | image[3]) != width)
153  {
154  return false;
155  }
156 
157  // read each component
158  for (int i = 0; i < 4; i++)
159  {
160  for (int j = 0; j < width; )
161  {
162  s >> code;
163  if (s.atEnd())
164  {
165  return false;
166  }
167  if (code > 128)
168  {
169  // run
170  code &= 127;
171  s >> val;
172  while( code != 0 )
173  {
174  image[i + j * 4] = val;
175  j++;
176  code--;
177  }
178  }
179  else
180  {
181  // non-run
182  while( code != 0 )
183  {
184  s >> image[i + j * 4];
185  j++;
186  code--;
187  }
188  }
189  }
190  }
191 
192  RGBE_To_QRgbLine(image.data(), scanline, width);
193  }
194 
195  return true;
196  }
197 
198 } // namespace
199 
200 
201 KDE_EXPORT void kimgio_hdr_read( QImageIO * io )
202 {
203  int len;
204  char line[MAXLINE];
205  //bool validHeader = false;
206  bool validFormat = false;
207 
208  // Parse header
209  do {
210  len = io->ioDevice()->readLine(line, MAXLINE);
211 
212  /*if (strcmp(line, "#?RADIANCE\n") == 0 || strcmp(line, "#?RGBE\n") == 0)
213  {
214  validHeader = true;
215  }*/
216  if (strcmp(line, "FORMAT=32-bit_rle_rgbe\n") == 0)
217  {
218  validFormat = true;
219  }
220 
221  } while((len > 0) && (line[0] != '\n'));
222 
223  if( !validFormat )
224  {
225  kDebug(399) << "Unknown HDR format.";
226  io->setImage( 0 );
227  io->setStatus( -1 );
228  return;
229  }
230 
231  io->ioDevice()->readLine(line, MAXLINE);
232 
233  char s1[3], s2[3];
234  int width, height;
235  if (sscanf(line, "%2[+-XY] %d %2[+-XY] %d\n", s1, &height, s2, &width) != 4)
236  //if( sscanf(line, "-Y %d +X %d", &height, &width) < 2 )
237  {
238  kDebug(399) << "Invalid HDR file.";
239  io->setImage( 0 );
240  io->setStatus( -1 );
241  return;
242  }
243 
244  QDataStream s( io->ioDevice() );
245 
246  QImage img;
247  if( !LoadHDR(s, width, height, img) )
248  {
249  kDebug(399) << "Error loading HDR file.";
250  io->setImage( 0 );
251  io->setStatus( -1 );
252  return;
253  }
254 
255  io->setImage( img );
256  io->setStatus( 0 );
257 }
258 
259 
260 KDE_EXPORT void kimgio_hdr_write( QImageIO * )
261 {
262  // intentionally not implemented (since writing low dynamic range data to a HDR file is nonsense.)
263 }
264 
QImage::scanLine
uchar * scanLine(int i)
MAXLINE
#define MAXLINE
Definition: hdr.cpp:22
MINELEN
#define MINELEN
Definition: hdr.cpp:23
QImage::create
bool create(const QSize &size, int depth, int numColors, Endian bitOrder)
kimgio_hdr_read
void kimgio_hdr_read(QImageIO *io)
Definition: hdr.cpp:201
QDataStream
QIODevice::at
Offset at() const
uchar
Q_UINT8 uchar
Definition: hdr.cpp:18
QDataStream::atEnd
bool atEnd() const
uchar
quint8 uchar
Definition: dds.cpp:38
QImage
kimgio_hdr_write
void kimgio_hdr_write(QImageIO *)
Definition: hdr.cpp:260
hdr.h
MAXELEN
#define MAXELEN
Definition: hdr.cpp:24
uint
quint32 uint
Definition: dds.cpp:36
QDataStream::device
QIODevice * device() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:49 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KImgIO

Skip menu "KImgIO"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal