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

KImgIO

  • 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
42static 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
84inline 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
103static 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
168static 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
213void 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}
pic_rw.h
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
BOTH
@ BOTH
Definition: pic_rw.h:44
RLE
@ RLE
Definition: pic_rw.h:52
BLUE
@ BLUE
Definition: pic_rw.h:61
ALPHA
@ ALPHA
Definition: pic_rw.h:62
GREEN
@ GREEN
Definition: pic_rw.h:60
RED
@ RED
Definition: pic_rw.h:59
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
FAIL
#define FAIL()
Definition: pic_write.cpp:206
convertABGRtoRGBA
unsigned convertABGRtoRGBA(unsigned pixel)
Definition: pic_write.cpp:84
pic_write
void pic_write(QIODevice *dev, const QImage *img)
Pic write handler for Qt / KDE.
Definition: pic_write.cpp:213
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
writeRow
static bool writeRow(QIODevice *dev, unsigned *row, unsigned width, bool alpha)
Writes a row to the file.
Definition: pic_write.cpp:168
PICChannel
PIC channel header.
Definition: pic_rw.h:83
PICChannel::type
char type
Definition: pic_rw.h:86
PICChannel::size
char size
Definition: pic_rw.h:85
PICChannel::channel
char channel
Definition: pic_rw.h:87
PICChannel::chained
char chained
Definition: pic_rw.h:84
PICHeader
PIC format header.
Definition: pic_rw.h:68
PICHeader::magic
qint32 magic
Definition: pic_rw.h:69
PICHeader::version
float version
Definition: pic_rw.h:70
PICHeader::width
qint16 width
Definition: pic_rw.h:73
PICHeader::id
char id[4]
Definition: pic_rw.h:72
PICHeader::ratio
float ratio
Definition: pic_rw.h:75
PICHeader::fields
qint16 fields
Definition: pic_rw.h:76
PICHeader::comment
char comment[80]
Definition: pic_rw.h:71
PICHeader::height
qint16 height
Definition: pic_rw.h:74
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
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