• 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
pic_write.cpp
Go to the documentation of this file.
1 
21 /* This code is based on the GIMP-PIC plugin by Halfdan Ingvarsson,
22  * and relicensed from GPL to LGPL to accomodate the KDE licensing policy
23  * with his permission.
24  * These is the original copyright:
25  * Copyright (C) 1998 Halfdan Ingvarsson
26  */
27 
28 #include "pic_rw.h"
29 #include <netinet/in.h>
30 #include <iostream>
31 #include <qimage.h>
32 
42 static bool writeHeader(QIODevice *dev, std::string msg, unsigned width, unsigned height, bool alpha) {
43  PICHeader h;
44  PICChannel c;
45  unsigned count = 0;
46 
47  memset(&h, 0, sizeof (PICHeader));
48  h.magic = htonl(PIC_MAGIC_NUMBER);
49  h.version = 3.71f;
50  strcpy(h.comment, msg.c_str());
51  strncpy(h.id, "PICT", 4);
52  h.width = htons(width);
53  h.height = htons(height);
54  h.ratio = 1.0f;
55  h.fields = htons(BOTH);
56  count = dev->write((const char*) & h, sizeof (PICHeader));
57  if (count != sizeof (PICHeader)) {
58  return false;
59  }
60 
61  memset(&c, 0, sizeof (PICChannel));
62  c.size = 8;
63  c.type = RLE;
64  c.channel = RED | GREEN | BLUE;
65  if (alpha) {
66  c.chained = 1;
67  }
68  count = dev->write((const char*) & c, sizeof (PICChannel));
69  if (count != sizeof (PICChannel)) {
70  return false;
71  }
72 
73  if (alpha) {
74  c.channel = ALPHA;
75  c.chained = 0;
76  count = dev->write((const char*) & c, sizeof (PICChannel));
77  if (count != sizeof (PICChannel)) {
78  return false;
79  }
80  }
81  return true;
82 }
83 
84 inline unsigned convertABGRtoRGBA(unsigned pixel) {
85  unsigned r = pixel & 0xFF;
86  unsigned g = (pixel >> 8) & 0xFF;
87  unsigned b = (pixel >> 16) & 0xFF;
88  unsigned a = (pixel >> 24) & 0xFF;
89  return a | (b << 8) | (g << 16) | (r << 24);
90 }
91 
103 static bool encodeRLE(const unsigned *image, unsigned char *output, bool rgb, unsigned max, unsigned &oConsumed, unsigned &oProduced) {
104  const unsigned *in = image;
105  unsigned char *out = output;
106  unsigned count = 0;
107  unsigned channels = 3;
108  unsigned offset = 1;
109  unsigned mask = 0x00FFFFFF;
110  if (!rgb) {
111  channels = 1;
112  offset = 0;
113  mask = 0xFF000000;
114  }
115  for (; (*in & mask) == (*image & mask) && count < 65536 && count < max; in++, count++) {
116  }
117  if (count > 127) {
118  /* Sequence of > 127 identical pixels */
119  *out++ = 128;
120  *out++ = count >> 8;
121  *out++ = count & 0xFF;
122  unsigned pixel = convertABGRtoRGBA(*image);
123  memcpy(out, ((char*) & pixel) + offset, channels);
124  out += channels;
125  oConsumed = count;
126  oProduced = out - output;
127  }
128  else if (count > 1) {
129  /* Sequece of < 128 identical pixels */
130  *out++ = (count + 127);
131  unsigned pixel = convertABGRtoRGBA(*image);
132  memcpy(out, ((char*) & pixel) + offset, channels);
133  out += channels;
134  oConsumed = count;
135  oProduced = out - output;
136  }
137  else {
138  in = image + 1;
139  unsigned previous = *image;
140  count = 0;
141  while ((*in & mask) != (previous & mask) && count < 128 && count < max) {
142  previous = *in;
143  in++;
144  count++;
145  }
146  // This only happens when it is the end of the row, and it is ok
147  if (count == 0) {
148  count = 1;
149  }
150  *out++ = (count - 1);
151  in = image;
152  for (unsigned c = 0; c < count; ++c) {
153  unsigned pixel = convertABGRtoRGBA(*in);
154  memcpy(out, ((char*) & pixel) + offset, channels);
155  out += channels;
156  in++;
157  }
158  oConsumed = count;
159  oProduced = out - output;
160  }
161  return true;
162 }
163 
168 static bool writeRow(QIODevice *dev, unsigned *row, unsigned width, bool alpha) {
169  unsigned char *buf = new unsigned char[width * 4];
170  unsigned posIn = 0;
171  unsigned posOut = 0;
172 
173  memset(buf, 0, width * 4);
174 
175  unsigned consumed = 0;
176  unsigned produced = 0;
177 
178  /* Write the RGB part of the scanline */
179  while (posIn < width) {
180  if (!encodeRLE(row + posIn, buf + posOut, true, width - posIn, consumed, produced)) {
181  delete[] buf;
182  return false;
183  }
184  posIn += consumed;
185  posOut += produced;
186  }
187 
188  /* Write the alpha channel */
189  if (alpha) {
190  posIn = 0;
191  while (posIn < width) {
192  if (!encodeRLE(row + posIn, buf + posOut, false, width - posIn, consumed, produced)) {
193  delete[] buf;
194  return false;
195  }
196  posIn += consumed;
197  posOut += produced;
198  }
199  }
200 
201  dev->write((const char*) buf, posOut);
202  delete[] buf;
203  return true;
204 }
205 
206 #define FAIL() { \
207  std::cout << "ERROR Writing PIC!" << std::endl; \
208  return; \
209 }
210 
212 
213 void pic_write(QIODevice *dev, const QImage *img) {
214  bool alpha = img->hasAlphaChannel();
215  if (!writeHeader(dev, "Created with KDE", img->width(), img->height(), alpha)) {
216  FAIL();
217  }
218 
219  for (int r = 0; r < img->height(); r++) {
220  unsigned *row = (unsigned*) img->scanLine(r);
221  if (!writeRow(dev, row, img->width(), alpha)) {
222  FAIL();
223  }
224  }
225 }
QIODevice
QImage::scanLine
uchar * scanLine(int i)
pic_rw.h
PICHeader::ratio
float ratio
Definition: pic_rw.h:75
PICChannel
PIC channel header.
Definition: pic_rw.h:83
PICHeader
PIC format header.
Definition: pic_rw.h:68
PICHeader::magic
qint32 magic
Definition: pic_rw.h:69
PICChannel::size
char size
Definition: pic_rw.h:85
QImage::hasAlphaChannel
bool hasAlphaChannel() const
PIC_MAGIC_NUMBER
#define PIC_MAGIC_NUMBER
PIC_RW - Qt PIC Support Copyright (C) 2007 Ruben Lopez r.lopez@bren.es
Definition: pic_rw.h:31
PICHeader::version
float version
Definition: pic_rw.h:70
PICChannel::channel
char channel
Definition: pic_rw.h:87
PICHeader::id
char id[4]
Definition: pic_rw.h:72
writeRow
static bool writeRow(QIODevice *dev, unsigned *row, unsigned width, bool alpha)
Writes a row to the file.
Definition: pic_write.cpp:168
convertABGRtoRGBA
unsigned convertABGRtoRGBA(unsigned pixel)
Definition: pic_write.cpp:84
QImage::width
int width() const
PICChannel::chained
char chained
Definition: pic_rw.h:84
RLE
Definition: pic_rw.h:52
pic_write
void pic_write(QIODevice *dev, const QImage *img)
Pic write handler for Qt / KDE.
Definition: pic_write.cpp:213
PICHeader::fields
qint16 fields
Definition: pic_rw.h:76
QImage
BLUE
Definition: pic_rw.h:61
BOTH
Definition: pic_rw.h:44
PICChannel::type
char type
Definition: pic_rw.h:86
encodeRLE
static bool encodeRLE(const unsigned *image, unsigned char *output, bool rgb, unsigned max, unsigned &oConsumed, unsigned &oProduced)
Encodes a portion of the image in RLE coding.
Definition: pic_write.cpp:103
QIODevice::write
qint64 write(const char *data, qint64 maxSize)
GREEN
Definition: pic_rw.h:60
QImage::height
int height() const
PICHeader::height
qint16 height
Definition: pic_rw.h:74
PICHeader::comment
char comment[80]
Definition: pic_rw.h:71
writeHeader
static bool writeHeader(QIODevice *dev, std::string msg, unsigned width, unsigned height, bool alpha)
PIC_RW - Qt PIC Support Copyright (C) 2007 Ruben Lopez r.lopez@bren.es
Definition: pic_write.cpp:42
ALPHA
Definition: pic_rw.h:62
RED
Definition: pic_rw.h:59
FAIL
#define FAIL()
Definition: pic_write.cpp:206
PICHeader::width
qint16 width
Definition: pic_rw.h:73
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