Compare commits

...

32 Commits

Author SHA1 Message Date
bc85e51774 [RELEASE] Release v1.0.0 2021-02-16 21:43:05 +01:00
7d89856b1f [DEBUG] update new API of lutin log 2019-05-03 10:18:22 +02:00
0bcfe53bc9 [DEV] use path in api cutter instead of string 2019-04-01 22:02:12 +02:00
aa9610f85d [DEV] add egami-cutter 2018-11-08 13:11:45 +01:00
437e6b3c18 [DEV] update new etk Uri API 2018-10-23 22:19:31 +02:00
c8863cde93 [DEV] update new URI 2018-10-09 23:03:07 +02:00
41a2c25992 [DEV] integrate the new interface of URI and file 2018-09-24 23:26:06 +02:00
37c83f9728 [DEV] update resize 2018-09-08 11:12:18 +02:00
8ef121b698 [DEV] update nullptr in null (specific etk) 2018-06-19 22:15:52 +02:00
8779e2011a [DEV] update typo toUpper toLower 2018-04-05 21:33:17 +02:00
f2dbed233f [DEBUG] build back tools 2017-11-07 10:18:48 +01:00
10be74f158 [DEV] update to the new ETK allocator wrapper 2017-10-21 19:05:21 +02:00
861f59061f [DEV] support of JPG compression ==> 1 thread only, code not finished 2017-10-14 10:50:46 +02:00
fc67e46de5 [DEV] write on buffer 2017-10-09 23:47:42 +02:00
99eae9d10f [DEV] add store in png 2017-10-09 22:22:48 +02:00
7965135796 [DEBUG] correct viewer 2017-10-09 10:18:19 +02:00
024d00adff [DEV] continue removing STL 2017-09-14 00:59:21 +02:00
c171d4a035 [DEBUG] correct read of bitmap file and store 2017-09-12 22:44:56 +02:00
eb5618aaac [DEV] remove STL 2017-09-07 23:38:26 +02:00
55c71b8ed9 [DEV] continue removing stl 2017-08-28 00:03:21 +02:00
e790937d29 [DEBUG] correct mine type of ffmpeg 2017-06-28 08:23:12 +02:00
1181bc52e7 [DEV] add an API to load raw buffer 2017-06-25 15:00:33 +02:00
f345c9c664 [DEV] add GPU size in images 2017-06-18 13:58:37 +02:00
b0eea46065 Change licence APACHE-2 to MPL-2 ==> force source redistribution and permit static link 2017-01-05 21:28:23 +01:00
b790073cab [DEV] duplicate the last line to have a better image view when upscale 2016-12-22 22:46:06 +01:00
db0bbb781f [DEBUG] correct test auto 2016-12-20 22:43:22 +01:00
2205f2ef8d [DEBUG] correct a back-line around the image resized and the copy of data when resized 2016-12-20 22:20:04 +01:00
130aeac190 [DEV] many correction on read write file
- BMP read write correction RGB order
  - JPG and PNG correct sens on the image
  - image private, correct the internal data
2016-12-20 22:00:03 +01:00
e628bba94f [DEBUG] try to corret reading of files 2016-12-19 23:01:20 +01:00
2d8af2d99c [DEV] start integration of JPEG, add test, correct the orientation of the image in the image and better storing of image in bmp 2016-12-19 22:27:16 +01:00
25e6b83253 [DEV] add swap in image 2016-11-16 21:07:05 +01:00
927604ad6d [DEV] update dev tag version 2016-10-24 22:23:26 +02:00
60 changed files with 3020 additions and 588 deletions

373
LICENSE Normal file
View File

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@ -65,15 +65,15 @@ Compile software:
lutin -C -P egami-test
License (APACHE v2.0)
License (MPL v2.0)
=====================
Copyright egami Edouard DUPIN
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the Mozilla Public License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
https://www.mozilla.org/MPL/2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

113
data/read.svg Normal file
View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg4152"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 64 64"
sodipodi:docname="test.svg">
<defs
id="defs4154">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective4706" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="-1"
inkscape:cy="32"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1021"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata4157">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<rect
style="fill:#f0d200;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4700"
width="43.454544"
height="33.454544"
x="7.818182"
y="6.909091" />
<ellipse
style="fill:#0002f0;fill-opacity:1;stroke:#00db92;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4702"
cx="44.272728"
cy="45.545456"
rx="16.09091"
ry="15.181818" />
<path
sodipodi:type="star"
style="fill:#00f04d;fill-opacity:1;stroke:#db0000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4704"
sodipodi:sides="5"
sodipodi:cx="24.727274"
sodipodi:cy="40.545455"
sodipodi:r1="16.39996"
sodipodi:r2="8.1999798"
sodipodi:arg1="0.066568164"
sodipodi:arg2="0.69488669"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 41.09091,41.636365 -10.065016,4.159525 -2.279495,10.649418 -7.066204,-8.287035 -10.832601,1.122923 5.697862,-9.281195 -4.415422,-9.955413 10.587677,2.550942 8.103721,-7.275707 0.845682,10.857763 z"
inkscape:transform-center-x="-1.2419781"
inkscape:transform-center-y="0.33710945" />
<path
sodipodi:type="star"
style="fill:#d000f0;fill-opacity:1;stroke:#001bdb;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4722"
sodipodi:sides="5"
sodipodi:cx="-8.181818"
sodipodi:cy="-6.3636365"
sodipodi:r1="43.930073"
sodipodi:r2="35.540176"
sodipodi:arg1="0.68572951"
sodipodi:arg2="1.314048"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 25.818183,21.454546 -49.950086,13.114031 -27.90761,-43.4528968 32.702234,-39.9693982 48.118702,18.750451 z"
inkscape:transform-center-x="3.447227"
inkscape:transform-center-y="-0.77893397" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
data/read2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
data/read3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
data/read4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
data/read_128x128.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
data/read_128x128.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
data/read_128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
data/read_227x149.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

BIN
data/read_227x149.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
data/read_227x149.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
data/read_228x149.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -50,16 +50,16 @@ Are there any licensing restrictions? {#egami_mainpage_license_restri
EGAMI is **FREE software** and _all sub-library are FREE and staticly linkable !!!_
License (APACHE-2.0) {#egami_mainpage_license}
====================
License (MPL v2.0) {#egami_mainpage_license}
==================
Copyright EGAMI Edouard DUPIN
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the Mozilla Public License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
<http://www.apache.org/licenses/LICENSE-2.0>
<https://www.mozilla.org/MPL/2.0>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <egami/Image.hpp>
@ -9,7 +9,12 @@
#include <egami/ImagePrivate.hpp>
#include <ememory/memory.hpp>
std::ostream& egami::operator <<(std::ostream& _os, const enum egami::colorType _type) {
etk::Stream& egami::operator <<(etk::Stream& _os, const egami::Image& _obj) {
_os << "egami::Image{" << _obj.getSize() << " on GPU: " << _obj.getGPUSize() << " color=" << _obj.getType();
return _os;
}
etk::Stream& egami::operator <<(etk::Stream& _os, const enum egami::colorType _type) {
switch (_type) {
case egami::colorType::undefined:
_os << "egami::colorType::undefined";
@ -42,34 +47,87 @@ std::ostream& egami::operator <<(std::ostream& _os, const enum egami::colorType
return _os;
}
int32_t egami::getFormatColorSize(enum colorType _type) {
switch (_type) {
case egami::colorType::undefined:
return 1;
break;
case egami::colorType::RGBA8:
return 1*4;
break;
case egami::colorType::RGB8:
return 1*3;
break;
case egami::colorType::RGBAf:
return 4*4;
break;
case egami::colorType::RGBf:
return 4*3;
break;
case egami::colorType::unsignedInt16:
return 2;
break;
case egami::colorType::unsignedInt32:
return 4;
break;
case egami::colorType::float32:
return 4;
break;
case egami::colorType::float64:
return 8;
break;
}
return 1;
}
egami::Image::Image() :
m_data(nullptr) {
m_data(null) {
}
egami::Image::Image(const egami::Image& _image):
m_data(_image.m_data) {
}
egami::Image& egami::Image::operator=(const egami::Image& _image) {
m_data = _image.m_data;
return *this;
}
egami::Image::~Image() {
}
egami::Image::Image(const ivec2& _size, enum colorType _type) :
m_data(nullptr) {
egami::Image::Image(const ivec2& _size,
enum colorType _type,
const void* _dataToCopy) :
m_data(null) {
configure(_size, _type);
if (_dataToCopy != null) {
memcpy(getTextureDataPointer(), _dataToCopy, getSize().x()*getSize().y()*egami::getFormatColorSize(getType()));
}
}
void egami::Image::swap(egami::Image& _obj) {
ememory::SharedPtr<ImagePrivate> tmp = m_data;
m_data = _obj.m_data;
_obj.m_data = tmp;
}
void egami::Image::configure(const ivec2& _size, enum colorType _type) {
switch (_type) {
case egami::colorType::undefined:
m_data = nullptr;
m_data = null;
break;
case egami::colorType::RGBA8:
//m_data = ememory::makeShared<egami::ImagePrivate>(new egami::ImageTemplate<etk::Color<uint8_t>>(_size));
m_data = ememory::makeShared<egami::ImageTemplate<etk::Color<uint8_t>>>(_size);
m_data = ememory::makeShared<egami::ImageTemplate<etk::Color<uint8_t, 4>>>(_size);
break;
case egami::colorType::RGB8:
m_data = ememory::makeShared<egami::ImageTemplate<etk::Color<uint8_t, 3>>>(_size);
break;
case egami::colorType::RGBAf:
m_data = ememory::makeShared<egami::ImageTemplate<etk::Color<float>>>(_size);
m_data = ememory::makeShared<egami::ImageTemplate<etk::Color<float, 4>>>(_size);
break;
case egami::colorType::RGBf:
m_data = ememory::makeShared<egami::ImageTemplate<etk::Color<float, 3>>>(_size);
@ -90,92 +148,127 @@ void egami::Image::configure(const ivec2& _size, enum colorType _type) {
}
enum egami::colorType egami::Image::getType() const {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return egami::colorType::undefined;
}
return m_data->getType();
}
void* egami::Image::getTextureDataPointer() {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
return nullptr;
void* egami::Image::getTextureDataPointer() const{
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return null;
}
return m_data->getTextureDataPointer();
return (void*)m_data->getTextureDataPointer();
}
void egami::Image::resize(const ivec2& _size, const ivec2& _startPos) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->resize(_size, _startPos);
m_data->resize2(_size, _startPos);
}
void egami::Image::resize(const ivec2& _size, const etk::Color<>& _color, const ivec2& _startPos) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->resize(_size, _color, _startPos);
}
void egami::Image::resize(const ivec2& _size, const etk::Color<float>& _color, const ivec2& _startPos) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->resize(_size, _color, _startPos);
}
void egami::Image::resize(const ivec2& _size, const etk::Color<uint16_t, 1>& _color, const ivec2& _startPos) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->resize(_size, _color, _startPos);
}
void egami::Image::resize(const ivec2& _size, const etk::Color<uint32_t, 1>& _color, const ivec2& _startPos) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->resize(_size, _color, _startPos);
}
void egami::Image::resize(const ivec2& _size, const etk::Color<float, 1>& _color, const ivec2& _startPos) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->resize(_size, _color, _startPos);
}
void egami::Image::resize(const ivec2& _size, const etk::Color<double, 1>& _color, const ivec2& _startPos) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->resize(_size, _color, _startPos);
}
const ivec2& egami::Image::getSize() const {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
static const ivec2 error(0,0);
return error;
}
return m_data->getSize();
}
#if defined(__TARGET_OS__Android) \
|| defined(__TARGET_OS__IOs)
/**
* @brief get the next power 2 if the input
* @param[in] value Value that we want the next power of 2
* @return result value
*/
static int32_t nextP2(int32_t _value) {
int32_t val=1;
for (int32_t iii=1; iii<31; iii++) {
if (_value <= val) {
return val;
}
val *=2;
}
EGAMI_CRITICAL("impossible CASE....");
return val;
}
#endif
ivec2 egami::Image::getGPUSize() const {
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
static const ivec2 error(0,0);
return error;
}
#if defined(__TARGET_OS__Android) \
|| defined(__TARGET_OS__IOs)
return ivec2(nextP2(m_data->getSize().x()),
nextP2(m_data->getSize().y()));
#else
return m_data->getSize();
#endif
}
int32_t egami::Image::getWidth() const {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return 0;
}
return m_data->getWidth();
}
int32_t egami::Image::getHeight() const {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return 0;
}
return m_data->getHeight();
@ -183,70 +276,70 @@ int32_t egami::Image::getHeight() const {
void egami::Image::scale(const ivec2& _size) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
resize(_size);
}
void egami::Image::clear(const etk::Color<>& _color) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->clear();
};
void egami::Image::clear(const etk::Color<float>& _color) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->clear();
};
void egami::Image::clear(const etk::Color<uint16_t, 1>& _color) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->clear();
};
void egami::Image::clear(const etk::Color<uint32_t, 1>& _color) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->clear();
};
void egami::Image::clear(const etk::Color<float, 1>& _color) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->clear();
};
void egami::Image::clear(const etk::Color<double, 1>& _color) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->clear();
};
etk::Color<> egami::Image::get(const ivec2& _pos) const {
if (m_data == nullptr) {
if (m_data == null) {
return etk::Color<>(0,0,0,0);
}
return m_data->get(_pos);;
}
void egami::Image::insert(const ivec2& _pos, const egami::Image& _input) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
if (_input.m_data == nullptr) {
EGAMI_DEBUG("No input data for image (nullptr)");
if (_input.m_data == null) {
EGAMI_DEBUG("No input data for image (null)");
return;
}
enum colorType destType = m_data->getType();
@ -264,64 +357,64 @@ void egami::Image::insert(const ivec2& _pos, const egami::Image& _input) {
}
void egami::Image::set(const ivec2& _pos, const etk::Color<>& _newColor) {
if (m_data == nullptr) {
EGAMI_WARNING("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_WARNING("No internal data for image (null)");
return;
}
m_data->set(_pos, _newColor);
}
void egami::Image::set(const ivec2& _pos, const etk::Color<float>& _newColor) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->set(_pos, _newColor);
}
void egami::Image::set(const ivec2& _pos, const etk::Color<uint16_t, 1>& _newColor) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->set(_pos, _newColor);
}
void egami::Image::set(const ivec2& _pos, const etk::Color<uint32_t, 1>& _newColor) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->set(_pos, _newColor);
}
void egami::Image::set(const ivec2& _pos, const etk::Color<float, 1>& _newColor) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->set(_pos, _newColor);
}
void egami::Image::set(const ivec2& _pos, const etk::Color<double, 1>& _newColor) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->set(_pos, _newColor);
}
void egami::Image::set(const std::vector<etk::Color<float,4>>& _data, const ivec2& _size) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
void egami::Image::set(const etk::Vector<etk::Color<float,4>>& _data, const ivec2& _size) {
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->set(_data, _size);
}
void egami::Image::set(const std::vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size) {
if (m_data == nullptr) {
EGAMI_DEBUG("No internal data for image (nullptr)");
void egami::Image::set(const etk::Vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size) {
if (m_data == null) {
EGAMI_DEBUG("No internal data for image (null)");
return;
}
m_data->set(_data, _size);

View File

@ -1,12 +1,12 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <vector>
#include <etk/Vector.hpp>
#include <etk/math/Vector2D.hpp>
#include <etk/Color.hpp>
#include <etk/stdTools.hpp>
@ -25,14 +25,20 @@ namespace egami {
float32,
float64,
};
std::ostream& operator <<(std::ostream& _os, const enum egami::colorType _obj);
etk::Stream& operator <<(etk::Stream& _os, const enum egami::colorType _obj);
/**
* @brief Get the Color size use in octet
* @param[in] type of the color
* @return Number of byte requested by the color
*/
int32_t getFormatColorSize(enum colorType _type);
class ImagePrivate {
public:
ImagePrivate() {};
virtual ~ImagePrivate() {};
virtual void* getTextureDataPointer() {
return nullptr;
virtual void* getTextureDataPointer() const {
return null;
};
virtual const ivec2& getSize() const = 0;
virtual int32_t getWidth() const {
@ -51,7 +57,7 @@ namespace egami {
virtual void resize(const ivec2& _size, const etk::Color<uint32_t, 1>& _color, const ivec2& _startPos) = 0;
virtual void resize(const ivec2& _size, const etk::Color<float, 1>& _color, const ivec2& _startPos) = 0;
virtual void resize(const ivec2& _size, const etk::Color<double, 1>& _color, const ivec2& _startPos) = 0;
virtual void resize(const ivec2& _size, const ivec2& _startPos) = 0;
virtual void resize2(const ivec2& _size, const ivec2& _startPos) = 0;
virtual void set(const ivec2& _pos, const etk::Color<>& _newColor) = 0;
virtual void set(const ivec2& _pos, const etk::Color<float>& _newColor) = 0;
virtual void set(const ivec2& _pos, const etk::Color<uint16_t, 1>& _newColor) = 0;
@ -59,8 +65,8 @@ namespace egami {
virtual void set(const ivec2& _pos, const etk::Color<float, 1>& _newColor) = 0;
virtual void set(const ivec2& _pos, const etk::Color<double, 1>& _newColor) = 0;
virtual etk::Color<> get(const ivec2& _pos) const = 0;
virtual void set(const std::vector<etk::Color<float,4>>& _data, const ivec2& _size) = 0;
virtual void set(const std::vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size) = 0;
virtual void set(const etk::Vector<etk::Color<float,4>>& _data, const ivec2& _size) = 0;
virtual void set(const etk::Vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size) = 0;
};
class Image {
@ -73,22 +79,27 @@ namespace egami {
* @note use @ref configure to set a correct image
*/
Image();
Image(const egami::Image& _image);
Image& operator=(const egami::Image& _image);
Image(const ivec2& _size,
enum colorType _type = egami::colorType::undefined);
enum colorType _type = egami::colorType::undefined,
const void* _dataToCopy = null);
~Image();
// TODO : IMplement move operator ... and copy operator...
public:
void configure(const ivec2& _size=ivec2(32,32),
enum colorType _type=egami::colorType::RGBA8);
void* getTextureDataPointer();
void* getTextureDataPointer() const;
enum colorType getType() const;
bool exist() {
return m_data != nullptr;
return m_data != null;
}
void swap(egami::Image& _obj);
// -----------------------------------------------
// -- basic tools :
// -- basic tools:
// -----------------------------------------------
public :
void move(const ivec2& _offset);
void resize(const ivec2& _size, const ivec2& _startPos=ivec2(0,0));
// TODO : Create a template function ...
void resize(const ivec2& _size, const etk::Color<>& _color, const ivec2& _startPos=ivec2(0,0));
@ -101,6 +112,7 @@ namespace egami {
const ivec2& getSize() const;
int32_t getWidth() const;
int32_t getHeight() const;
ivec2 getGPUSize() const;
void clear(const etk::Color<>& _color);
void clear(const etk::Color<float>& _color);
void clear(const etk::Color<uint16_t, 1>& _color);
@ -131,8 +143,9 @@ namespace egami {
*/
void scale(const ivec2& _size);
void set(const std::vector<etk::Color<float,4>>& _data, const ivec2& _size);
void set(const std::vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size);
void set(const etk::Vector<etk::Color<float,4>>& _data, const ivec2& _size);
void set(const etk::Vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size);
};
etk::Stream& operator <<(etk::Stream& _os, const egami::Image& _obj);
}

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <egami/ImageMono.hpp>

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once
@ -9,13 +9,13 @@
#include <etk/math/Vector2D.hpp>
#include <etk/Color.hpp>
#include <vector>
#include <etk/Vector.hpp>
namespace egami {
class ImageMono {
private:
ivec2 m_size;
std::vector<uint8_t> m_data;
etk::Vector<uint8_t> m_data;
public:
// constructor :
ImageMono(const ivec2& _size=ivec2(32,32));
@ -23,8 +23,8 @@ namespace egami {
~ImageMono() { };
// EWOL internal API for Texture system :
public:
void* getTextureDataPointer() {
return &m_data[0];
void* getTextureDataPointer() const {
return (void*)&m_data[0];
};
/*
enum colorType getType() {

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once
@ -10,22 +10,22 @@
#include <etk/Color.hpp>
#include <egami/debug.hpp>
#include <vector>
#include <etk/Vector.hpp>
namespace egami {
template<typename T = etk::Color<>>
template<typename EGAMI_TYPE_COLOR = etk::Color<>>
class ImageTemplate : public ImagePrivate {
private:
ivec2 m_size;
std::vector<T> m_data;
etk::Vector<EGAMI_TYPE_COLOR> m_data;
public:
// constructor :
ImageTemplate(const ivec2& _size=ivec2(32,32)) :
m_size(_size) {
// basic element :
// basic element:
etk::Color<> tmpBg(0,0,0,0);
// preallocate data with a basic bg elements :
// preallocate data with a basic bg elements:
m_data.resize(m_size.x()*m_size.y(), tmpBg);
if ((uint32_t)m_size.x()*m_size.y() > m_data.size()) {
//TK_ERROR("Allocation of data buffer in error");
@ -35,73 +35,105 @@ namespace egami {
// destructor
virtual ~ImageTemplate() { };
// EWOL internal API for Texture system :
// EWOL internal API for Texture system:
public:
void* getTextureDataPointer() {
return &m_data[0];
void* getTextureDataPointer() const {
return (void*)&m_data[0];
};
enum colorType getType() const;
const ivec2& getSize() {
return m_size;
};
// -----------------------------------------------
// -- basic tools :
// -- basic tools:
// -----------------------------------------------
public :
void resize__(const ivec2& _size, const ivec2& _startPos=ivec2(0,0)) {
void resize2__(const ivec2& _size, const ivec2& _startPos=ivec2(0,0)) {
move(-_startPos);
if (_size == m_size) {
// same size == > nothing to do ...
return;
}
if ((size_t)(_size.x()*_size.y()) > m_data.size()) {
m_data.resize(_size.x()*_size.y());
ivec2 oldSize = m_size;
m_size = _size;
if ((size_t)(m_size.x()*m_size.y()) > m_data.size()) {
m_data.resize(m_size.x()*m_size.y());
}
// grow size :
if (_size.x() == m_size.x()) {
if (_size.y() < m_size.y()) {
if (m_size.x() == oldSize.x()) {
if (m_size.y() < oldSize.y()) {
// Just remove lines ....
} else {
// just add lines
}
} else if (_size.x() < m_size.x()) {
if (_size.y() <= m_size.y()) {
for (int32_t yyy=0; yyy<_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<_size.x(); ++xxx) {
m_data[yyy*_size.x()+xxx] = m_data[yyy*m_size.x()+xxx];
} else if (m_size.x() < oldSize.x()) {
if (m_size.y() <= oldSize.y()) {
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
m_data[yyy*m_size.x()+xxx] = m_data[yyy*oldSize.x()+xxx];
}
}
} else {
for (int32_t yyy=m_size.y()-1; yyy>=0; --yyy) {
for (int32_t xxx=0; xxx<_size.x(); ++xxx) {
m_data[yyy*_size.x()+xxx] = m_data[yyy*m_size.x()+xxx];
for (int32_t yyy=oldSize.y()-1; yyy>=0; --yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
m_data[yyy*m_size.x()+xxx] = m_data[yyy*oldSize.x()+xxx];
}
}
}
} else { // (_size.x() > m_size.x())
} else { // (m_size.x() > oldSize.x())
if (_size.y() <= m_size.y()) {
for (int32_t yyy=0; yyy<_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
m_data[yyy*_size.x()+xxx] = m_data[yyy*m_size.x()+xxx];
if (m_size.y() <= oldSize.y()) {
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<oldSize.x(); ++xxx) {
m_data[yyy*m_size.x()+xxx] = m_data[yyy*oldSize.x()+xxx];
}
}
} else {
for (int32_t yyy=m_size.y()-1; yyy>=0; --yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
m_data[yyy*_size.x()+xxx] = m_data[yyy*m_size.x()+xxx];
for (int32_t yyy=oldSize.y()-1; yyy>=0; --yyy) {
for (int32_t xxx=oldSize.x()-1; xxx>=0; --xxx) {
m_data[yyy*m_size.x()+xxx] = m_data[yyy*oldSize.x()+xxx];
}
}
}
}
if ((size_t)(_size.x()*_size.y()) < m_data.size()) {
m_data.resize(_size.x()*_size.y());
if ((size_t)(m_size.x()*m_size.y()) < m_data.size()) {
m_data.resize(m_size.x()*m_size.y());
}
// Clean all Data outside old range:
// basic element:
etk::Color<> tmpBg(0,0,0,0);
for (int32_t yyy=oldSize.y(); yyy<m_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
set(ivec2(xxx,yyy), tmpBg);
}
if (yyy==oldSize.y()) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
set(ivec2(xxx,yyy), etk::Color<>(m_data[(yyy-1)*oldSize.x()+xxx]));
}
}
}
for (int32_t xxx=oldSize.x(); xxx<m_size.x(); ++xxx) {
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
set(ivec2(xxx,yyy), tmpBg);
}
if (xxx==oldSize.x()) {
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
set(ivec2(xxx,yyy), etk::Color<>(m_data[yyy*oldSize.x()+oldSize.x()-1]));
}
}
}
m_size = _size;
}
void resize__(const ivec2& _size, const T& _color) {
void resize__(const ivec2& _size, const EGAMI_TYPE_COLOR& _color) {
m_size=_size;
m_data.resize(m_size.x()*m_size.y(), _color);
}
void move(const ivec2& _offset) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
set(ivec2(xxx,yyy), get(ivec2(xxx-_offset.x(),yyy-_offset.y())));
}
}
}
void resize(const ivec2& _size, const etk::Color<uint8_t, 4>& _color, const ivec2& _startPos) {
resize__(_size, _color);
@ -122,11 +154,11 @@ namespace egami {
resize__(_size, _color);
}
void resize(const ivec2& _size, const ivec2& _startPos) {
resize__(_size);
void resize2(const ivec2& _size, const ivec2& _startPos) {
resize2__(_size, _startPos);
}
template<typename TYPE_2> void resize(const ivec2& _size, const TYPE_2& _color) {
T tmp(_color);
template<typename EGAMI_TYPE_COLOR_2> void resize(const ivec2& _size, const EGAMI_TYPE_COLOR_2& _color) {
EGAMI_TYPE_COLOR tmp(_color);
resize__(_size, tmp);
}
void set(const ivec2& _pos, const etk::Color<>& _newColor) {
@ -157,33 +189,33 @@ namespace egami {
int32_t getHeight() const {
return m_size.y();
};
void clearColor(const T& _fill) {
void clearColor(const EGAMI_TYPE_COLOR& _fill) {
for (int32_t iii=0; iii<m_size.x()*m_size.y(); iii++) {
m_data[iii] = _fill;
}
}
void clear() {
clearColor(T::emptyColor);
clearColor(EGAMI_TYPE_COLOR::emptyColor);
}
etk::Color<> get(const ivec2& _pos) const {
return get__(_pos);
}
const T& get__(const ivec2& _pos) const {
static const T errorColor(0x00000000);
if( _pos.x()>0 && _pos.x()<m_size.x()
&& _pos.y()>0 && _pos.y()<m_size.y()) {
const EGAMI_TYPE_COLOR& get__(const ivec2& _pos) const {
static const EGAMI_TYPE_COLOR errorColor(0x00000000);
if( _pos.x()>=0 && _pos.x()<m_size.x()
&& _pos.y()>=0 && _pos.y()<m_size.y()) {
return m_data[_pos.x()+_pos.y()*m_size.x()];
}
return errorColor;
}
void set__(const ivec2& _pos, const T& _newColor) {
void set__(const ivec2& _pos, const EGAMI_TYPE_COLOR& _newColor) {
if( _pos.x()>=0 && _pos.x()<m_size.x()
&& _pos.y()>=0 && _pos.y()<m_size.y()) {
m_data[_pos.x()+_pos.y()*m_size.x()] = _newColor;
}
}
void insert(const ivec2& _pos, const ImageTemplate<T>& _input) {
void insert(const ivec2& _pos, const ImageTemplate<EGAMI_TYPE_COLOR>& _input) {
for(int32_t yyy = 0; yyy < _input.getSize().y() && _pos.y() + yyy < m_size.y(); ++yyy) {
for(int32_t xxx = 0; xxx < _input.getSize().x() && _pos.x() + xxx < m_size.x(); ++xxx) {
set(ivec2(_pos.x()+xxx, _pos.y()+yyy), _input.get(ivec2(xxx, yyy)) );
@ -199,8 +231,8 @@ namespace egami {
// TODO : Add capabilities ...
int32_t stepX = m_size.x() / _size.x();
int32_t stepY = m_size.y() / _size.y();
stepX = std::max(1, stepX);
stepY = std::max(1, stepY);
stepX = etk::max(1, stepX);
stepY = etk::max(1, stepY);
EGAMI_VERBOSE("move : " << stepX << " , " << stepY << " from : " << m_size << " ==> " << _size);
for (int32_t yyy = 0; yyy < _size.y(); ++yyy) {
for (int32_t xxx = 0; xxx < _size.x(); ++xxx) {
@ -209,7 +241,7 @@ namespace egami {
}
resize(_size);
}
void set(const std::vector<etk::Color<float,4>>& _data, const ivec2& _size) {
void set(const etk::Vector<etk::Color<float,4>>& _data, const ivec2& _size) {
m_data.clear();
m_size = _size;
m_data.resize(_data.size());
@ -217,7 +249,7 @@ namespace egami {
m_data[iii] = _data[iii];
}
}
void set(const std::vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size) {
void set(const etk::Vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size) {
m_data.clear();
m_size = _size;
m_data.resize(_data.size());

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <egami/debug.hpp>

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once

View File

@ -1,95 +1,235 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <egami/egami.hpp>
#include <egami/debug.hpp>
#include <egami/wrapperSVG.hpp>
#include <egami/wrapperPNG.hpp>
#ifdef EGAMI_BUILD_ESVG
#include <egami/wrapperSVG.hpp>
#endif
#ifdef EGAMI_BUILD_PNG
#include <egami/wrapperPNG.hpp>
#endif
#include <egami/wrapperBMP.hpp>
#include <egami/wrapperEDF.hpp>
#ifdef EGAMI_BUILD_JPEG
#include <egami/wrapperJPG.hpp>
#endif
#ifdef EGAMI_BUILD_JPEG2000
#include <egami/wrapperJPG2000.hpp>
#endif
#ifdef EGAMI_BUILD_TIFF
#include <egami/wrapperTIFF.hpp>
#endif
#include <edtaa3/edtaa3func.h>
bool egami::scalable(const std::string& _fileName) {
if (true == etk::end_with(_fileName, ".svg") ) {
bool egami::scalable(const etk::Uri& _uri) {
if (etk::toLower(_uri.getPath().getExtention()) == "svg") {
return true;
}
return false;
}
egami::Image egami::load(const std::string& _fileName, const ivec2& _size) {
std::string tmpName = etk::tolower(_fileName);
egami::Image egami::load(const etk::Uri& _uri, const ivec2& _size) {
etk::String extention = etk::toLower(_uri.getPath().getExtention());
egami::Image out;
// select the corect Loader :
if (etk::end_with(tmpName, ".edf") == true) {
EGAMI_ERROR("parse file '" << _uri << "' extention=" << extention);
if (extention == "edf") {
// internal format for ewol distance field ==> simple sistance field image
out = egami::loadEDF(_fileName);
out = egami::loadEDF(_uri);
if (out.exist() == false) {
EGAMI_ERROR("Error to load EDF file '" << _fileName << "'");
EGAMI_ERROR("Error to load EDF file '" << _uri << "'");
}
} else if (etk::end_with(tmpName, ".bmp") == true) {
out = egami::loadBMP(_fileName);
} else if (extention == "bmp") {
out = egami::loadBMP(_uri);
if (out.exist() == false) {
EGAMI_ERROR("Error to load BMP file '" << _fileName << "'");
}
} else if (etk::end_with(tmpName, ".svg") == true) {
out = egami::loadSVG(_fileName, _size);
if (out.exist() == false) {
EGAMI_ERROR("Error to load SVG file '" << _fileName << "'");
}
//egami::storeEDF(_fileName + ".edf", _output);
} else if (etk::end_with(tmpName, ".png") == true) {
out = egami::loadPNG(_fileName);
if (out.exist() == false) {
EGAMI_ERROR("Error to load PNG file '" << _fileName << "'");
EGAMI_ERROR("Error to load BMP file '" << _uri << "'");
}
} else if (extention == "svg") {
#ifdef EGAMI_BUILD_ESVG
out = egami::loadSVG(_uri, _size);
if (out.exist() == false) {
EGAMI_ERROR("Error to load SVG file '" << _uri << "'");
}
#else
EGAMI_WARNING("egami not compile with the ESVG dependency for file '" << _uri << "'");
#endif
} else if (extention == "png") {
#ifdef EGAMI_BUILD_PNG
out = egami::loadPNG(_uri);
if (out.exist() == false) {
EGAMI_ERROR("Error to load PNG file '" << _uri << "'");
}
#else
EGAMI_WARNING("egami not compile with the PNG dependency for file '" << _uri << "'");
#endif
} else if (extention == "jpg") {
#ifdef EGAMI_BUILD_JPEG
out = egami::loadJPG(_uri);
if (out.exist() == false) {
EGAMI_ERROR("Error to load JPG file '" << _uri << "'");
}
#else
EGAMI_WARNING("egami not compile with the JPEG dependency for file '" << _uri << "'");
#endif
} else if (extention == "j2k") {
#ifdef EGAMI_BUILD_JPEG2000
out = egami::loadJPG2000(_uri);
if (out.exist() == false) {
EGAMI_ERROR("Error to load JPEG2000 file '" << _uri << "'");
}
#else
EGAMI_WARNING("egami not compile with the JPEG 2000 (openjpeg) dependency for file '" << _uri << "'");
#endif
} else if (extention == "tif") {
#ifdef EGAMI_BUILD_TIFF
out = egami::loadTIFF(_uri);
if (out.exist() == false) {
EGAMI_ERROR("Error to load TIFF file '" << _uri << "'");
}
#else
EGAMI_WARNING("egami not compile with the TIFF dependency for file '" << _uri << "'");
#endif
} else {
EGAMI_ERROR("Extention not managed '" << _fileName << "' Sopported extention : .edf / .bmp / .svg / .png");
EGAMI_ERROR("Extention not managed '" << _uri << "' Sopported extention : .edf / .bmp / .svg / .png / .jpg / .j2k / .tif");
}
return out;
}
bool egami::store(const egami::Image& _input, const std::string& _fileName) {
std::string tmpName = etk::tolower(_fileName);
EGAMI_DEBUG("Store file : " << _fileName);
egami::Image egami::load(const etk::String& _mineType, const etk::Vector<uint8_t>& _buffer, const ivec2& _size) {
egami::Image out;
// select the corect Loader :
if (etk::end_with(tmpName, ".edf") == true) {
if (egami::storeEDF(_fileName, _input) == false) {
EGAMI_ERROR("Error to store EDF file '" << _fileName << "'");
if (_mineType == "image/bmp") {
out = egami::loadBMP(_buffer);
if (out.exist() == false) {
EGAMI_ERROR("Error to load BMP file '" << _buffer.size() << "'");
}
}else if (_mineType == "image/png") {
#ifdef EGAMI_BUILD_PNG
out = egami::loadPNG(_buffer);
if (out.exist() == false) {
EGAMI_ERROR("Error to load PNG file '" << _buffer.size() << "'");
}
#else
EGAMI_WARNING("egami not compile with the PNG dependency for file '" << _buffer.size() << "'");
#endif
} else if (_mineType == "image/jpeg") {
#ifdef EGAMI_BUILD_JPEG
out = egami::loadJPG(_buffer);
if (out.exist() == false) {
EGAMI_ERROR("Error to load JPG file '" << _buffer.size() << "'");
}
#else
EGAMI_WARNING("egami not compile with the JPEG dependency for file '" << _buffer.size() << "'");
#endif
} else {
EGAMI_ERROR("Extention not managed '" << _mineType << "' Sopported extention : image/bmp, image/png, image/jpg");
}
return out;
}
bool egami::store(const egami::Image& _input, const etk::Uri& _uri) {
etk::String extention = etk::toLower(_uri.getPath().getExtention());
EGAMI_DEBUG("Store file : " << _uri);
// select the corect Loader :
if (extention == "edf") {
if (egami::storeEDF(_uri, _input) == false) {
EGAMI_ERROR("Error to store EDF file '" << _uri << "'");
return false;
}
} else if (etk::end_with(tmpName, ".bmp") == true) {
if (egami::storeBMP(_fileName, _input) == false) {
EGAMI_ERROR("Error to store BMP file '" << _fileName << "'");
} else if (extention == "bmp") {
if (egami::storeBMP(_uri, _input) == false) {
EGAMI_ERROR("Error to store BMP file '" << _uri << "'");
return false;
}
} else if (etk::end_with(tmpName, ".svg") == true) {
EGAMI_ERROR("Can not store in SVG file '" << _fileName << "'");
} else if (extention == "svg") {
EGAMI_ERROR("Can not store in SVG file '" << _uri << "'");
return false;
} else if (etk::end_with(tmpName, ".png") == true) {
EGAMI_ERROR("Can not store in PNG file '" << _fileName << "'");
} else if (extention == "png") {
#ifdef EGAMI_BUILD_PNG
if (egami::storePNG(_uri, _input) == false) {
EGAMI_ERROR("Error to store PNG file '" << _uri << "'");
return false;
}
#else
EGAMI_WARNING("egami not compile with the PNG dependency for file '" << _uri << "'");
return false;
#endif
} else if (extention == "jpg") {
#ifdef EGAMI_BUILD_JPEG
if (egami::storeJPG(_uri, _input) == false) {
EGAMI_ERROR("Error to store JPEG file '" << _uri << "'");
return false;
}
#else
EGAMI_WARNING("egami not compile with the JPEG dependency for file '" << _uri << "'");
return false;
#endif
} else if (extention == "j2k") {
EGAMI_ERROR("Can not store in JPEG 2000 file '" << _uri << "'");
return false;
} else if (extention == "tif") {
EGAMI_ERROR("Can not store in TIFF file '" << _uri << "'");
return false;
} else {
EGAMI_ERROR("Extention not managed '" << _fileName << "' Sopported extention: .edf / .bmp / .svg / .png");
EGAMI_ERROR("Extention not managed '" << _uri << "' Sopported extention: .edf / .bmp / .svg / .png / .jpg / .j2k / .tif");
return false;
}
return true;
}
bool egami::store(const egami::Image& _input, etk::Vector<uint8_t>& _buffer, const etk::String& _mineType) {
// clear output data.
_buffer.clear();
// select the corect Loader :
if (_mineType == "image/bmp") {
if (egami::storeBMP(_buffer, _input) == false) {
EGAMI_ERROR("Error to store BMP for Raw output");
return false;
}
}else if (_mineType == "image/png") {
#ifdef EGAMI_BUILD_PNG
if (egami::storePNG(_buffer, _input) == false) {
EGAMI_ERROR("Error to store PNG for Raw output");
return false;
}
#else
EGAMI_WARNING("egami not compile with the PNG dependency for Raw output");
return false;
#endif
} else if (_mineType == "image/jpeg") {
#ifdef EGAMI_BUILD_JPEG
if (egami::storeJPG(_buffer, _input) == false) {
EGAMI_ERROR("Error to store JPG for Raw output");
return false;
}
#else
EGAMI_WARNING("egami not compile with the JPG dependency for Raw output");
return false;
#endif
return false;
} else {
EGAMI_ERROR("Extention not managed for Raw output Sopported extention: .bmp / .png / .jpg");
return false;
}
return true;
}
static void generateDistanceField(const egami::ImageMono& _input, egami::Image& _output) {
int32_t size = _input.getSize().x() * _input.getSize().y();
std::vector<short> xdist(size);
std::vector<short> ydist(size);
std::vector<double> gx(size);
std::vector<double> gy(size);
std::vector<double> data(size);
std::vector<double> outside(size);
std::vector<double> inside(size);
etk::Vector<short> xdist(size);
etk::Vector<short> ydist(size);
etk::Vector<double> gx(size);
etk::Vector<double> gy(size);
etk::Vector<double> data(size);
etk::Vector<double> outside(size);
etk::Vector<double> inside(size);
/*
// Convert img into double (data)
double img_min = 255, img_max = -255;
@ -163,9 +303,10 @@ static void generateDistanceField(const egami::ImageMono& _input, egami::Image&
}
bool egami::generateDistanceFieldFile(const std::string& _input, const std::string& _output) {
bool egami::generateDistanceFieldFile(const etk::Uri& _input, const etk::Uri& _output) {
egami::Image data;
if (etk::end_with(_input, ".edf") == true) {
etk::String extention = etk::toLower(_input.getPath().getExtention());
if (extention == "edf") {
return false;
}
EGAMI_ERROR("Generate distance field : '" << _input << "' ==> '" << _output << "'");

View File

@ -1,37 +1,53 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <vector>
#include <etk/Vector.hpp>
#include <etk/math/Vector2D.hpp>
#include <etk/Color.hpp>
#include <egami/Image.hpp>
#include <egami/ImageMono.hpp>
#include <etk/uri/Uri.hpp>
namespace egami {
/**
* @brief Load a specific ilage file in the requested image data.
* @param[in] _fileName Name of the file (SVG, BMP, PNG).
* @param[in] _uri Uri of the file (SVG, BMP, PNG).
* @param[in] _size Dimention of the file when resizable (SVG).
*/
egami::Image load(const std::string& _fileName, const ivec2& _size=ivec2(-1,-1) );
egami::Image load(const etk::Uri& _uri, const ivec2& _size=ivec2(-1,-1) );
/**
* @brief Load a specific ilage file in the requested image data.
* @param[in] _mineType mineType of the buffer.
* @param[in] _buffer memory file.
* @param[in] _size Dimention of the file when resizable (SVG).
*/
egami::Image load(const etk::String& _mineType, const etk::Vector<uint8_t>& _buffer, const ivec2& _size=ivec2(-1,-1) );
/**
* @brief Save an image in a file.
* @param[in] _input Data of the image.
* @param[in] _fileName Name of the file.
* @param[in] _uri Uri of the file.
* @return true if the file is corectly Stored, false otherwise
*/
bool store(const egami::Image& _input, const std::string& _fileName);
bool store(const egami::Image& _input, const etk::Uri& _uri);
/**
* @brief Save an image in a memory buffer.
* @param[in] _input Data of the image.
* @param[out] _buffer Store file in this buffer.
* @param[in] _mineType mineType of the output buffer.
* @return true if the file is corectly Stored, false otherwise
*/
bool store(const egami::Image& _input, etk::Vector<uint8_t>& _buffer, const etk::String& _mineType);
/**
* @brief know if a file can have multiple size definition.
* @param[in] _fileName Name of the file.
* @param[in] _uri Uri of the file.
* @return true if the format is scalable.
*/
bool scalable(const std::string& _fileName);
bool scalable(const etk::Uri& _uri);
/**
* @brief Generate a distance field output file from an input file;
* @param[in] _input Input file name
@ -39,7 +55,7 @@ namespace egami {
* @return true All done corectly.
* @return false An error occured.
*/
bool generateDistanceFieldFile(const std::string& _input, const std::string& _output);
bool generateDistanceFieldFile(const etk::Uri& _input, const etk::Uri& _output);
}

View File

@ -1,14 +1,14 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <etk/types.hpp>
#include <egami/debug.hpp>
#include <egami/Image.hpp>
#include <egami/wrapperBMP.hpp>
#include <etk/os/FSNode.hpp>
#include <etk/uri/uri.hpp>
extern "C" {
#pragma pack(push,1)
struct bitmapFileHeader {
@ -27,8 +27,28 @@ extern "C" {
int32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
int32_t biClrUsed;
int32_t biClrImportant;
int32_t biPaletteNumber;
int32_t biImportantColor;
};
struct bitmapInfoHeaderExtended {
int32_t biSize;
int32_t biWidth;
int32_t biHeight;
int16_t biPlanes;
int16_t biBitCount;
int32_t biCompression;
int32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
// https://en.wikipedia.org/wiki/BMP_file_format / example 2
int32_t biPaletteNumber;
int32_t biImportantColor;
int32_t biLCSColorSpace; // This is at this position, inspection of "gimp" output ...
int32_t biBitMaskRed;
int32_t biBitMaskGreen;
int32_t biBitMaskBlue;
int32_t biBitMaskAlpha;
int32_t biUnused[12];
};
#pragma pack(pop)
}
@ -40,53 +60,122 @@ enum modeBitmap {
BITS_32_A8R8G8B8
};
egami::Image egami::loadBMP(const std::string& _inputFile) {
static void display(struct bitmapFileHeader _header, struct bitmapInfoHeader _info) {
EGAMI_DEBUG(" -----------------------------------------------------------");
EGAMI_DEBUG("Display caracteristic of the bitmap : ");
EGAMI_DEBUG(" Header of file :");
EGAMI_DEBUG(" bfType =" << _header.bfType << " 19778 : must always be set to 'BM' to declare that this is a .bmp-file.");
EGAMI_DEBUG(" bfSize =" << _header.bfSize << " specifies the size of the file in bytes.");
EGAMI_DEBUG(" bfReserved=" << _header.bfReserved << " must always be set to zero.");
EGAMI_DEBUG(" bfOffBits =" << _header.bfOffBits << " 1078 : specifies the offset from the beginning of the file to the bitmap data.");
EGAMI_DEBUG(" info header of file :");
EGAMI_DEBUG(" biSize =" << _info.biSize << " specifies the size of the BITMAPINFOHEADER structure, in bytes.");
EGAMI_DEBUG(" biWidth =" << _info.biWidth << " specifies the width of the image, in pixels.");
EGAMI_DEBUG(" biHeight =" << _info.biHeight << " specifies the height of the image, in pixels.");
EGAMI_DEBUG(" biPlanes =" << _info.biPlanes << " specifies the number of planes of the target device, must be set to zero.");
EGAMI_DEBUG(" biBitCount =" << _info.biBitCount << " specifies the number of bits per pixel.");
EGAMI_DEBUG(" biCompression =" << _info.biCompression << " Specifies the type of compression, usually set to zero (no compression).");
EGAMI_DEBUG(" biSizeImage =" << _info.biSizeImage << " specifies the size of the image data, in bytes. If there is no compression, it is valid to set this member to zero.");
EGAMI_DEBUG(" biXPelsPerMeter=" << _info.biXPelsPerMeter << " specifies the the horizontal pixels per meter on the designated targer device, usually set to zero.");
EGAMI_DEBUG(" biYPelsPerMeter=" << _info.biYPelsPerMeter << " specifies the the vertical pixels per meter on the designated targer device, usually set to zero.");
EGAMI_DEBUG(" biClrUsed =" << _info.biPaletteNumber << " Pallet color number.");
EGAMI_DEBUG(" biClrImportant =" << _info.biImportantColor << " Important color ID.");
/*
EGAMI_DEBUG("Bitmap : " << m_width << "x" << m_height);
switch(m_dataMode)
{
case BITS_16_R5G6B5:
EGAMI_DEBUG(" mode = 16 bits R5G6B5");
break;
case BITS_16_X1R5G5B5:
EGAMI_DEBUG(" mode = 16 bits X1R5G5B5");
break;
case BITS_24_R8G8B8:
EGAMI_DEBUG(" mode = 24 bits R8G8B8");
break;
case BITS_32_X8R8G8B8:
EGAMI_DEBUG(" mode = 32 bits X8R8G8B8");
break;
case BITS_32_A8R8G8B8:
EGAMI_DEBUG(" mode = 32 bits A8R8G8B8");
break;
default:
EGAMI_DEBUG(" mode = ERROR");
break;
}*/
}
egami::Image egami::loadBMP(const etk::Uri& _uri) {
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return egami::Image();
}
if (fileIo->open(etk::io::OpenMode::Read) == false) {
EGAMI_ERROR("Can not open (r) the file : " << _uri);
return egami::Image();
}
etk::Vector<uint8_t> allData = fileIo->readAll<uint8_t>();
fileIo->close();
return egami::loadBMP(allData);
}
egami::Image egami::loadBMP(const etk::Vector<uint8_t>& _buffer) {
egami::Image out;
enum modeBitmap m_dataMode = BITS_16_R5G6B5;
int32_t m_width = 0;
int32_t m_height = 0;
struct bitmapFileHeader m_FileHeader;
bool useExtended = false;
struct bitmapInfoHeader m_InfoHeader;
etk::FSNode fileName(_inputFile);
// get the fileSize ...
/*if (fileName.size() < (int32_t)(sizeof(struct bitmapFileHeader) + sizeof(struct bitmapFileHeader) ) ) {
EWOL_ERROR("not enought data in the file named=\"" << fileName << "\"");
return;
}*/
if (fileName.exist() == false) {
EGAMI_ERROR("File does not existed=\"" << fileName << "\"");
return out;
}
if(fileName.fileOpenRead() ==false) {
EGAMI_ERROR("Can not find the file name=\"" << fileName << "\"");
return out;
}
// get the data :
if (fileName.fileRead(&m_FileHeader,sizeof(struct bitmapFileHeader),1) != 1) {
EGAMI_ERROR("error loading file header");
fileName.fileClose();
return out;
}
if (fileName.fileRead(&m_InfoHeader,sizeof(struct bitmapInfoHeader),1) != 1) {
EGAMI_ERROR("error loading file header");
fileName.fileClose();
return out;
}
if(fileName.fileSeek(m_FileHeader.bfOffBits, etk::seekNode_start) == false) {
EGAMI_ERROR("error with the 'bfOffBits' in the file named=\"" << fileName << "\"");
fileName.fileClose();
struct bitmapInfoHeaderExtended m_InfoHeaderExtended;
if (_buffer.size() < sizeof(struct bitmapFileHeader)) {
EGAMI_ERROR("error loading file header, not enough data");
return out;
}
memcpy(&m_FileHeader, &_buffer[0], sizeof(struct bitmapFileHeader));
// check the header error :
if (m_FileHeader.bfType != 0x4D42) {
EGAMI_ERROR("the file=\"" << fileName << "\" is not a bitmap file ...");
fileName.fileClose();
EGAMI_ERROR("the Buffer is not a bitmap file ... " << m_FileHeader.bfType << " != " << 0x4D42);
return out;
}
if (m_FileHeader.bfOffBits > sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeader)) {
EGAMI_DEBUG("Read bitmap in EXTENDED mode ...");
if (_buffer.size() < sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeaderExtended)) {
EGAMI_ERROR("error loading file header, not enough data");
return out;
}
memcpy(&m_InfoHeaderExtended, &_buffer[sizeof(struct bitmapFileHeader)], sizeof(struct bitmapInfoHeaderExtended));
useExtended = true;
m_InfoHeader.biSize = m_InfoHeaderExtended.biSize;
m_InfoHeader.biWidth = m_InfoHeaderExtended.biWidth;
m_InfoHeader.biHeight = m_InfoHeaderExtended.biHeight;
m_InfoHeader.biHeight = m_InfoHeaderExtended.biHeight;
m_InfoHeader.biHeight = m_InfoHeaderExtended.biHeight;
m_InfoHeader.biBitCount = m_InfoHeaderExtended.biBitCount;
m_InfoHeader.biCompression = m_InfoHeaderExtended.biCompression;
m_InfoHeader.biSizeImage = m_InfoHeaderExtended.biSizeImage;
m_InfoHeader.biXPelsPerMeter = m_InfoHeaderExtended.biXPelsPerMeter;
m_InfoHeader.biYPelsPerMeter = m_InfoHeaderExtended.biYPelsPerMeter;
} else {
EGAMI_DEBUG("Read bitmap in BASIC mode ...");
if (_buffer.size() < sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeader)) {
EGAMI_ERROR("error loading file header, not enough data");
return out;
}
memcpy(&m_InfoHeader, &_buffer[sizeof(struct bitmapFileHeader)], sizeof(struct bitmapInfoHeader));
useExtended = false;
}
int32_t offsetHeader = m_FileHeader.bfOffBits;
display(m_FileHeader, m_InfoHeader);
// check the header error :
if (m_FileHeader.bfType != 0x4D42) {
EGAMI_ERROR("the Buffer is not a bitmap file ... " << m_FileHeader.bfType << " != " << 0x4D42);
return out;
}
if (m_FileHeader.bfReserved != 0x00000000) {
EGAMI_ERROR("the bfReserved feald is not at 0 == > not supported format ...");
fileName.fileClose();
return out;
}
m_width = m_InfoHeader.biWidth;
@ -113,86 +202,95 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
out.configure(ivec2(m_width,m_height), egami::colorType::RGBA8);
} else {
EGAMI_ERROR("the biBitCount & biCompression fealds are unknow == > not supported format ...");
fileName.fileClose();;
return out;
}
std::vector<uint8_t> m_data;
if(m_InfoHeader.biSizeImage != 0) {
m_data.resize(m_InfoHeader.biSizeImage, 0);
if (fileName.fileRead(&m_data[0],m_InfoHeader.biSizeImage,1) != 1){
if (_buffer.size() < offsetHeader + m_InfoHeader.biSizeImage) {
EGAMI_CRITICAL("Can not read the file with the good size...");
}
}
fileName.fileClose();
etk::Color<> tmpColor(0,0,0,0);
// need now to generate RGBA data ...
switch(m_dataMode) {
case BITS_16_R5G6B5: {
uint16_t * pointer = (uint16_t*)(&m_data[0]);
const uint16_t * pointer = (const uint16_t*)(&_buffer[offsetHeader]);
for(int32_t yyy=0; yyy<m_height; yyy++) {
for(int32_t xxx=0; xxx<m_width; xxx++) {
tmpColor.setR((uint8_t)((*pointer & 0xF800) >> 8));
tmpColor.setB((uint8_t)((*pointer & 0xF800) >> 8));
tmpColor.setG((uint8_t)((*pointer & 0x07E0) >> 3));
tmpColor.setB((uint8_t)(*pointer << 3));
tmpColor.setR((uint8_t)(*pointer << 3));
tmpColor.setA(0xFF);
out.set(ivec2(xxx,yyy), tmpColor);
out.set(ivec2(xxx,m_height-yyy-1), tmpColor);
pointer++;
}
}
}
break;
case BITS_16_X1R5G5B5: {
uint16_t * pointer = (uint16_t*)(&m_data[0]);
const uint16_t * pointer = (const uint16_t*)(&_buffer[offsetHeader]);
for(int32_t yyy=0; yyy<m_height; yyy++) {
for(int32_t xxx=0; xxx<m_width; xxx++) {
tmpColor.setR((int8_t)((*pointer & 0x7C00) >> 7));
tmpColor.setB((int8_t)((*pointer & 0x7C00) >> 7));
tmpColor.setG((int8_t)((*pointer & 0x03E0) >> 2));
tmpColor.setB((int8_t)(*pointer << 3));
tmpColor.setR((int8_t)(*pointer << 3));
tmpColor.setA(0xFF);
out.set(ivec2(xxx,yyy), tmpColor);
out.set(ivec2(xxx,m_height-yyy-1), tmpColor);
pointer++;
}
}
}
break;
case BITS_24_R8G8B8: {
uint8_t * pointer = (&m_data[0]);
int32_t offset = 0;
int32_t baseLine = m_width * 3;
if ((baseLine%4) == 1) {
offset = 3;
} else if ((baseLine%4) == 2) {
offset = 2;
} else if ((baseLine%4) == 3) {
offset = 1;
}
const uint8_t * pointer = (&_buffer[offsetHeader]);
for(int32_t yyy=0; yyy<m_height; yyy++) {
for(int32_t xxx=0; xxx<m_width; xxx++) {
tmpColor.setR(*pointer++);
tmpColor.setG(*pointer++);
tmpColor.setB(*pointer++);
tmpColor.setG(*pointer++);
tmpColor.setR(*pointer++);
tmpColor.setA(0xFF);
out.set(ivec2(xxx,yyy), tmpColor);
out.set(ivec2(xxx,m_height-yyy-1), tmpColor);
}
for(int32_t xxx=0; xxx<offset; xxx++) {
pointer++;
}
}
}
break;
case BITS_32_X8R8G8B8: {
uint8_t * pointer = (&m_data[0]);
const uint8_t * pointer = (&_buffer[offsetHeader]);
for(int32_t yyy=0; yyy<m_height; yyy++) {
for(int32_t xxx=0; xxx<m_width; xxx++) {
pointer++;
tmpColor.setR(*pointer++);
tmpColor.setG(*pointer++);
tmpColor.setB(*pointer++);
tmpColor.setG(*pointer++);
tmpColor.setR(*pointer++);
tmpColor.setA(0xFF);
out.set(ivec2(xxx,yyy), tmpColor);
out.set(ivec2(xxx,m_height-yyy-1), tmpColor);
}
}
}
break;
case BITS_32_A8R8G8B8: {
uint8_t * pointer = (&m_data[0]);
const uint8_t * pointer = (&_buffer[offsetHeader]);
for(int32_t yyy=0; yyy<m_height; yyy++) {
for(int32_t xxx=0; xxx<m_width; xxx++) {
tmpColor.setR(*pointer++);
tmpColor.setG(*pointer++);
tmpColor.setB(*pointer++);
tmpColor.setG(*pointer++);
tmpColor.setR(*pointer++);
tmpColor.setA(*pointer++);
out.set(ivec2(xxx,yyy), tmpColor);
out.set(ivec2(xxx,m_height-yyy-1), tmpColor);
}
}
}
@ -204,49 +302,79 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
return out;
}
bool egami::storeBMP(const std::string& _fileName, const egami::Image& _inputImage) {
#if 1
// Extended mode
bool egami::storeBMP(const etk::Uri& _uri, const egami::Image& _inputImage) {
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return false;
}
if (fileIo->open(etk::io::OpenMode::Write) == false) {
EGAMI_ERROR("Can not open (w) the file : " << _uri);
return false;
}
etk::Vector<uint8_t> allData;
bool ret = storeBMP(allData, _inputImage);
fileIo->writeAll(allData);
fileIo->close();
return ret;
}
bool egami::storeBMP(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage) {
_buffer.clear();
_buffer.reserve( _inputImage.getSize().x()*_inputImage.getSize().y()*getFormatColorSize(_inputImage.getType())
+ sizeof(struct bitmapInfoHeaderExtended)
+ sizeof(struct bitmapFileHeader));
struct bitmapFileHeader m_FileHeader;
struct bitmapInfoHeader m_InfoHeader;
struct bitmapInfoHeaderExtended m_InfoHeaderExtended;
memset(&m_InfoHeaderExtended, 0, sizeof(bitmapInfoHeaderExtended));
m_FileHeader.bfType = 0x4D42;
m_FileHeader.bfSize = sizeof(struct bitmapFileHeader);
m_FileHeader.bfSize = sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeaderExtended);
m_FileHeader.bfReserved = 0;
m_FileHeader.bfOffBits = 40;
m_InfoHeader.biSize = sizeof(struct bitmapInfoHeader);
m_InfoHeader.biWidth = _inputImage.getSize().x();
m_InfoHeader.biHeight = _inputImage.getSize().y();
m_InfoHeader.biPlanes = 1;
m_FileHeader.bfOffBits = sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeaderExtended);
//EGAMI_ERROR("plopppppppppppppp " << m_FileHeader.bfOffBits);
m_InfoHeaderExtended.biSize = sizeof(struct bitmapInfoHeaderExtended);
m_InfoHeaderExtended.biWidth = _inputImage.getSize().x();
m_InfoHeaderExtended.biHeight = _inputImage.getSize().y();
m_InfoHeaderExtended.biPlanes = 1;
int32_t offset = 0;
if (_inputImage.getType() == egami::colorType::RGBA8) {
m_InfoHeader.biBitCount = 32;
m_InfoHeader.biCompression = 0;
m_InfoHeader.biSizeImage = _inputImage.getSize().x()*_inputImage.getSize().y()*4;
m_InfoHeaderExtended.biBitCount = 32;
m_InfoHeaderExtended.biCompression = 0;
m_InfoHeaderExtended.biSizeImage = _inputImage.getSize().x()*_inputImage.getSize().y()*4;
} else {
m_InfoHeader.biBitCount = 24;
m_InfoHeader.biCompression = 0;
m_InfoHeader.biSizeImage = _inputImage.getSize().x()*_inputImage.getSize().y()*3;
m_InfoHeaderExtended.biBitCount = 24;
m_InfoHeaderExtended.biCompression = 0;
int32_t baseLine = _inputImage.getSize().x() * 3;
if ((baseLine%4) == 1) {
offset = 3;
} else if ((baseLine%4) == 2) {
offset = 2;
} else if ((baseLine%4) == 3) {
offset = 1;
}
m_InfoHeaderExtended.biSizeImage = (baseLine+offset)*_inputImage.getSize().y();
}
m_InfoHeader.biXPelsPerMeter = 75;
m_InfoHeader.biYPelsPerMeter = 75;
m_InfoHeader.biClrUsed = 0;
m_InfoHeader.biClrImportant = 0;
m_FileHeader.bfSize += m_InfoHeaderExtended.biSizeImage;
m_InfoHeaderExtended.biXPelsPerMeter = 72*39.3701+1;
m_InfoHeaderExtended.biYPelsPerMeter = 72*39.3701+1;
//m_InfoHeaderExtended.biClrUsed = 0;
//m_InfoHeaderExtended.biClrImportant = 0;
m_InfoHeaderExtended.biLCSColorSpace = 0x73524742; // "Win "
//display(m_FileHeader, m_InfoHeaderExtended);
m_InfoHeaderExtended.biBitMaskRed = 0x0000FF00;
m_InfoHeaderExtended.biBitMaskGreen = 0x00FF0000;
m_InfoHeaderExtended.biBitMaskBlue = 0xFF000000;
m_InfoHeaderExtended.biBitMaskAlpha = 0x000000FF;
_buffer.pushBack((uint8_t*)&m_FileHeader, sizeof(struct bitmapFileHeader));
_buffer.pushBack((uint8_t*)&m_InfoHeaderExtended, sizeof(struct bitmapInfoHeaderExtended));
etk::FSNode fileName(_fileName);
if(false == fileName.fileOpenWrite() ) {
EGAMI_ERROR("Can not find the file name=\"" << fileName << "\"");
return false;
}
// get the data:
if (fileName.fileWrite(&m_FileHeader,sizeof(struct bitmapFileHeader),1) != 1) {
EGAMI_ERROR("error loading file header");
fileName.fileClose();
return false;
}
if (fileName.fileWrite(&m_InfoHeader,sizeof(struct bitmapInfoHeader),1) != 1) {
EGAMI_ERROR("error loading file header");
fileName.fileClose();
return false;
}
/* TODO: Avec ca, ca ne fonctionne pas ... ==> check
if(fileName.fileSeek(m_FileHeader.bfOffBits, etk::FSN_SEEK_START) == false) {
EGAMI_ERROR("error with the 'bfOffBits' in the file named=\"" << fileName << "\"");
@ -258,81 +386,143 @@ bool egami::storeBMP(const std::string& _fileName, const egami::Image& _inputIma
uint8_t data[16];
for(int32_t yyy=0; yyy<_inputImage.getSize().y(); ++yyy) {
for(int32_t xxx=0; xxx<_inputImage.getSize().x(); ++xxx) {
const etk::Color<>& tmpColor = _inputImage.get(ivec2(xxx,yyy));
const etk::Color<>& tmpColor = _inputImage.get(ivec2(xxx,_inputImage.getSize().y()-yyy-1));
uint8_t* pointer = data;
*pointer++ = tmpColor.r();
*pointer++ = tmpColor.g();
*pointer++ = tmpColor.b();
*pointer++ = tmpColor.a();
fileName.fileWrite(data,4,1);
_buffer.pushBack(data, 4);
}
}
} else {
uint8_t data[16];
for(int32_t yyy=0; yyy<_inputImage.getSize().y(); ++yyy) {
for(int32_t xxx=0; xxx<_inputImage.getSize().x(); ++xxx) {
const etk::Color<>& tmpColor = _inputImage.get(ivec2(xxx,yyy));
const etk::Color<>& tmpColor = _inputImage.get(ivec2(xxx,_inputImage.getSize().y()-yyy-1));
uint8_t* pointer = data;
*pointer++ = tmpColor.b();
*pointer++ = tmpColor.g();
*pointer++ = tmpColor.r();
_buffer.pushBack(data, 3);
}
if (offset != 0) {
uint8_t pointer[4];
pointer[0] = 0;
pointer[1] = 0;
pointer[2] = 0;
pointer[3] = 0;
_buffer.pushBack(pointer, offset);
}
}
}
return true;
}
#else
// old mode:
bool egami::storeBMP(const etk::Uri& _uri, const egami::Image& _inputImage) {
struct bitmapFileHeader m_FileHeader;
struct bitmapInfoHeader m_InfoHeader;
memset(&m_InfoHeader, 0, sizeof(bitmapInfoHeader));
m_FileHeader.bfType = 0x4D42;
m_FileHeader.bfSize = sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeader);
m_FileHeader.bfReserved = 0;
m_FileHeader.bfOffBits = sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeader);
//EGAMI_ERROR("plopppppppppppppp " << m_FileHeader.bfOffBits);
m_InfoHeader.biSize = sizeof(struct bitmapInfoHeader);
m_InfoHeader.biWidth = _inputImage.getSize().x();
m_InfoHeader.biHeight = _inputImage.getSize().y();
m_InfoHeader.biPlanes = 1;
int32_t offset = 0;
if (_inputImage.getType() == egami::colorType::RGBA8) {
m_InfoHeader.biBitCount = 32;
m_InfoHeader.biCompression = 0;
m_InfoHeader.biSizeImage = _inputImage.getSize().x()*_inputImage.getSize().y()*4;
} else {
m_InfoHeader.biBitCount = 24;
m_InfoHeader.biCompression = 0;
int32_t baseLine = _inputImage.getSize().x() * 3;
if ((baseLine%4) == 1) {
offset = 3;
} else if ((baseLine%4) == 2) {
offset = 2;
} else if ((baseLine%4) == 3) {
offset = 1;
}
m_InfoHeader.biSizeImage = (baseLine+offset)*_inputImage.getSize().y();
}
m_FileHeader.bfSize += m_InfoHeader.biSizeImage;
m_InfoHeader.biXPelsPerMeter = 72*39.3701+1;
m_InfoHeader.biYPelsPerMeter = 72*39.3701+1;
//m_InfoHeader.biClrUsed = 0;
//m_InfoHeader.biClrImportant = 0;
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return false;
}
if (fileIo->open(etk::io::OpenMode::Write) == false) {
EGAMI_ERROR("Can not open (w) the file : " << _uri);
return false;
}
// Write header:
if (fileIo->write(&m_FileHeader,sizeof(struct bitmapFileHeader),1) != 1) {
EGAMI_ERROR("error loading file header");
fileIo->close();
return false;
}
if (fileIo->write(&m_InfoHeader,sizeof(struct bitmapInfoHeader),1) != 1) {
EGAMI_ERROR("error loading file header");
fileIo->close();
return false;
}
EGAMI_ERROR("header size = " << sizeof(struct bitmapFileHeader) << " + " << sizeof(struct bitmapInfoHeader) << " = " << (sizeof(struct bitmapFileHeader)+sizeof(struct bitmapInfoHeader)) );
/* TODO: Avec ca, ca ne fonctionne pas ... ==> check
if(fileName.fileSeek(m_FileHeader.bfOffBits, etk::FSN_SEEK_START) == false) {
EGAMI_ERROR("error with the 'bfOffBits' in the file named=\"" << fileName << "\"");
fileName.fileClose();
return false;
}
*/
if (_inputImage.getType() == egami::colorType::RGBA8) {
uint8_t data[16];
for(int32_t yyy=0; yyy<_inputImage.getSize().y(); ++yyy) {
for(int32_t xxx=0; xxx<_inputImage.getSize().x(); ++xxx) {
const etk::Color<>& tmpColor = _inputImage.get(ivec2(xxx,_inputImage.getSize().y()-yyy-1));
uint8_t* pointer = data;
*pointer++ = tmpColor.r();
*pointer++ = tmpColor.g();
*pointer++ = tmpColor.b();
fileName.fileWrite(data,3,1);
*pointer++ = tmpColor.a();
fileIo->write(data,4,1);
}
}
} else {
uint8_t data[16];
for(int32_t yyy=0; yyy<_inputImage.getSize().y(); ++yyy) {
for(int32_t xxx=0; xxx<_inputImage.getSize().x(); ++xxx) {
const etk::Color<>& tmpColor = _inputImage.get(ivec2(xxx,_inputImage.getSize().y()-yyy-1));
uint8_t* pointer = data;
*pointer++ = tmpColor.b();
*pointer++ = tmpColor.g();
*pointer++ = tmpColor.r();
fileIo->write(data,3,1);
}
if (offset != 0) {
uint8_t pointer[4];
pointer[0] = 0;
pointer[1] = 0;
pointer[2] = 0;
pointer[3] = 0;
fileIo->write(pointer,1,offset);
}
}
}
fileName.fileClose();
fileIo->close();
return true;
}
#endif
/*
void ewol::texture::TextureBMP::display()
{
if (NULL == m_data) {
EWOL_ERROR("Might loading error of this Bitmap ...");
return;
}
EWOL_DEBUG(" -----------------------------------------------------------");
if (false) {
EWOL_DEBUG("Display caracteristic of the bitmap : ");
EWOL_DEBUG(" Header of file :");
EWOL_DEBUG(" bfType =" << m_FileHeader.bfType << " 19778 : must always be set to 'BM' to declare that this is a .bmp-file.");
EWOL_DEBUG(" bfSize =" << m_FileHeader.bfSize << " specifies the size of the file in bytes.");
EWOL_DEBUG(" bfReserved=" << m_FileHeader.bfReserved << " must always be set to zero.");
EWOL_DEBUG(" bfOffBits =" << m_FileHeader.bfOffBits << " 1078 : specifies the offset from the beginning of the file to the bitmap data.");
EWOL_DEBUG(" info header of file :");
EWOL_DEBUG(" biSize =" << m_InfoHeader.biSize << " specifies the size of the BITMAPINFOHEADER structure, in bytes.");
EWOL_DEBUG(" biWidth =" << m_InfoHeader.biWidth << " specifies the width of the image, in pixels.");
EWOL_DEBUG(" biHeight =" << m_InfoHeader.biHeight << " specifies the height of the image, in pixels.");
EWOL_DEBUG(" biPlanes =" << m_InfoHeader.biPlanes << " specifies the number of planes of the target device, must be set to zero.");
EWOL_DEBUG(" biBitCount =" << m_InfoHeader.biBitCount << " specifies the number of bits per pixel.");
EWOL_DEBUG(" biCompression =" << m_InfoHeader.biCompression << " Specifies the type of compression, usually set to zero (no compression).");
EWOL_DEBUG(" biSizeImage =" << m_InfoHeader.biSizeImage << " specifies the size of the image data, in bytes. If there is no compression, it is valid to set this member to zero.");
EWOL_DEBUG(" biXPelsPerMeter=" << m_InfoHeader.biXPelsPerMeter << " specifies the the horizontal pixels per meter on the designated targer device, usually set to zero.");
EWOL_DEBUG(" biYPelsPerMeter=" << m_InfoHeader.biYPelsPerMeter << " specifies the the vertical pixels per meter on the designated targer device, usually set to zero.");
EWOL_DEBUG(" biClrUsed =" << m_InfoHeader.biClrUsed << " speglTexImage2Dcifies the number of colors used in the bitmap, if set to zero the number of colors is calculated using the biBitCount member.");
EWOL_DEBUG(" biClrImportant =" << m_InfoHeader.biClrImportant << " specifies the number of color that are 'important' for the bitmap, if set to zero, all colors are important.");
}
EWOL_DEBUG("Bitmap : " << m_width << "x" << m_height);
switch(m_dataMode)
{
case BITS_16_R5G6B5:
EWOL_DEBUG(" mode = 16 bits R5G6B5");
break;
case BITS_16_X1R5G5B5:
EWOL_DEBUG(" mode = 16 bits X1R5G5B5");
break;
case BITS_24_R8G8B8:
EWOL_DEBUG(" mode = 24 bits R8G8B8");
break;
case BITS_32_X8R8G8B8:
EWOL_DEBUG(" mode = 32 bits X8R8G8B8");
break;
case BITS_32_A8R8G8B8:
EWOL_DEBUG(" mode = 32 bits A8R8G8B8");
break;
default:
EWOL_DEBUG(" mode = ERROR");
break;
}
}
*/

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once
@ -10,17 +10,30 @@
namespace egami {
/**
* @breif Load a bmp file in the image.
* @param[in] _fileName Name of the file.
* @param[in] _uri Uri of the file.
* @return Generate image or empty image
*/
egami::Image loadBMP(const std::string& _fileName);
egami::Image loadBMP(const etk::Uri& _uri);
/**
* @breif Load a bmp file in the image.
* @param[in] _buffer file buffer
* @return Generate image or empty image
*/
egami::Image loadBMP(const etk::Vector<uint8_t>& _buffer);
/**
* @breif Store a bmp file in the image.
* @param[in] _fileName Name of the file.
* @param[in] _uri Uri of the file.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storeBMP(const std::string& _fileName, const egami::Image& _inputImage);
bool storeBMP(const etk::Uri& _uri, const egami::Image& _inputImage);
/**
* @breif Store a bmp file in the image.
* @param[out] _buffer output file buffer.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storeBMP(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage);
}

View File

@ -1,39 +1,39 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <etk/types.hpp>
#include <egami/debug.hpp>
#include <egami/Image.hpp>
#include <egami/wrapperEDF.hpp>
#include <etk/os/FSNode.hpp>
#include <etk/uri/uri.hpp>
//EDF format is a simple format for image in text for distance field image (special case)
// it is composed of the fist line : description of type (starting with #EDF and some other information, the data start just after the first \n
egami::Image egami::loadEDF(const std::string& _inputFile) {
egami::Image egami::loadEDF(const etk::Uri& _uri) {
egami::Image out;
etk::FSNode file(_inputFile);
if (false == file.exist()) {
EGAMI_ERROR("File does not existed='" << file << "'");
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return out;
}
if(false == file.fileOpenRead() ) {
EGAMI_ERROR("Can not find the file name='" << file << "'");
if (fileIo->open(etk::io::OpenMode::Read) == false) {
EGAMI_ERROR("Can not open (r) the file : " << _uri);
return out;
}
std::string line;
file.fileGets(line);
etk::String line;
fileIo->gets(line);
if (etk::start_with(line, "#edf", false) == false) {
EGAMI_ERROR("This file seams not to be a EDF file ...");
file.fileClose();
fileIo->close();
return out;
}
// count number of colomn max an number of line max:
ivec2 size(0,0);
while (file.fileGets(line) == true) {
while (fileIo->gets(line) == true) {
if (line.size()/2 > (size_t)size.x()) {
size.setValue(line.size()/2, size.y()+1);
} else {
@ -45,19 +45,17 @@ egami::Image egami::loadEDF(const std::string& _inputFile) {
} else {
size += ivec2(0,1);
}
EGAMI_DEBUG("'" << file << "' ==> size=" << size);
EGAMI_DEBUG("'" << _uri << "' ==> size=" << size);
// jup to the start of the file
file.fileSeek(0, etk::seekNode_start);
fileIo->seek(0, etk::io::SeekMode::Start);
// drop the first line
file.fileGets(line);
fileIo->gets(line);
// resize output:
out.configure(size, egami::colorType::RGB8); // TODO : Do it better
int32_t currentLineId = 0;
char tmp[3];
tmp[2] = '\0';
while (file.fileGets(line) == true) {
while (fileIo->gets(line) == true) {
if (line.size() <= 0) {
continue;
}
@ -79,26 +77,30 @@ egami::Image egami::loadEDF(const std::string& _inputFile) {
out.set(ivec2(xxx/2, currentLineId), etk::Color<>((uint8_t)val, (uint8_t)val, (uint8_t)val, (uint8_t)val));
}
}
file.fileClose();
fileIo->close();
return out;
}
bool egami::storeEDF(const std::string& _fileName, const egami::Image& _inputImage) {
bool egami::storeEDF(const etk::Uri& _uri, const egami::Image& _inputImage) {
bool anErrorEccured = false;
etk::FSNode file(_fileName);
if (file.fileOpenWrite() == false) {
EGAMI_ERROR("Can not find the file name=\"" << file << "\"");
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return false;
}
anErrorEccured = file.filePuts( std::string("#EDF // Generate with EGAMI (")
+ etk::to_string(_inputImage.getSize().x())
+ ","
+ etk::to_string(_inputImage.getSize().y()) + ")\n");
if (fileIo->open(etk::io::OpenMode::Write) == false) {
EGAMI_ERROR("Can not open (w) the file : " << _uri);
return false;
}
anErrorEccured = fileIo->puts( etk::String("#EDF // Generate with EGAMI (")
+ etk::toString(_inputImage.getSize().x())
+ ","
+ etk::toString(_inputImage.getSize().y()) + ")\n");
char tmp[256];
for (int32_t yyy = 0; yyy < _inputImage.getSize().y(); ++yyy) {
if (yyy != 0) {
if (file.filePut('\n') == false) {
if (fileIo->put('\n') == false) {
anErrorEccured = false;
}
}
@ -109,12 +111,11 @@ bool egami::storeEDF(const std::string& _fileName, const egami::Image& _inputIma
EGAMI_DEBUG(" set : " << _inputImage.get(ivec2(xxx, yyy)) << " : '" << tmp << "'");
}
*/
if (file.filePuts(tmp) == false) {
if (fileIo->puts(tmp) == false) {
anErrorEccured = false;
}
}
}
file.fileClose();
fileIo->close();
return anErrorEccured;
}

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once
@ -19,16 +19,16 @@ namespace egami {
* * *
* *
* [PRE]
* @param[in] _fileName Name of the file.
* @param[in] _uri Uri of the file.
* @return Read Image
*/
egami::Image loadEDF(const std::string& _fileName);
egami::Image loadEDF(const etk::Uri& _uri);
/**
* @breif Store a edf file in the image.
* @param[in] _fileName Name of the file.
* @param[in] _uri Uri of the file.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storeEDF(const std::string& _fileName, const egami::Image& _inputImage);
bool storeEDF(const etk::Uri& _uri, const egami::Image& _inputImage);
}

301
egami/wrapperJPG.cpp Normal file
View File

@ -0,0 +1,301 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etk/types.hpp>
#include <egami/debug.hpp>
#include <egami/Image.hpp>
#include <egami/wrapperJPG.hpp>
#include <etk/uri/uri.hpp>
extern "C" {
#include "jpeglib.h"
}
#include <setjmp.h>
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
/*
* Here's the routine that will replace the standard error_exit method:
*/
METHODDEF(void) my_error_exit(j_common_ptr _cinfo) {
// cinfo->err really points to a my_error_mgr struct, so coerce pointer
my_error_ptr myerr = (my_error_ptr)_cinfo->err;
// Always display the message.
// We could postpone this until after returning, if we chose.
(*_cinfo->err->output_message)(_cinfo);
// Return control to the setjmp point
longjmp(myerr->setjmp_buffer, 1);
}
void put_scanline_someplace(const uint8_t* _buffer, int32_t _row_stride) {
EGAMI_ERROR("plop " << uint64_t(_buffer) << " row=" << _row_stride << " " << (_row_stride/3));
}
egami::Image egami::loadJPG(const etk::Uri& _uri) {
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return egami::Image();
}
if (fileIo->open(etk::io::OpenMode::Read) == false) {
EGAMI_ERROR("Can not open (r) the file : " << _uri);
return egami::Image();
}
etk::Vector<uint8_t> allData = fileIo->readAll<uint8_t>();
fileIo->close();
return egami::loadJPG(allData);
}
egami::Image egami::loadJPG(const etk::Vector<uint8_t>& _buffer) {
egami::Image out;
// This struct contains the JPEG decompression parameters and pointers to working space (which is allocated as needed by the JPEG library).
struct jpeg_decompress_struct cinfo;
// We use our private extension JPEG error handler. Note that this struct must live as long as the main JPEG parameter struct, to avoid dangling-pointer problems.
struct my_error_mgr jerr;
// More stuff
JSAMPARRAY buffer;
int row_stride;
// Step 1: allocate and initialize JPEG decompression object
// We set up the normal JPEG error routines, then override error_exit.
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
// Establish the setjmp return context for my_error_exit to use.
if (setjmp(jerr.setjmp_buffer)) {
// If we get here, the JPEG code has signaled an error. We need to clean up the JPEG object, close the input file, and return.
jpeg_destroy_decompress(&cinfo);
return out;
}
// Now we can initialize the JPEG decompression object.
jpeg_create_decompress(&cinfo);
// Step 2: specify data source (eg, a file)
jpeg_mem_src(&cinfo, &_buffer[0], _buffer.size());
// Step 3: read file parameters with jpeg_read_header()
(void)jpeg_read_header(&cinfo, TRUE);
// We can ignore the return value from jpeg_read_header since
// (a) suspension is not possible with the stdio data source, and
// (b) we passed TRUE to reject a tables-only JPEG file as an error.
// See libjpeg.txt for more info.
// Step 4: set parameters for decompression
// In this example, we don't need to change any of the defaults set by jpeg_read_header(), so we do nothing here.
// Step 5: Start decompressor
(void) jpeg_start_decompress(&cinfo);
// We can ignore the return value since suspension is not possible with the stdio data source.
// We may need to do some setup of our own at this point before reading the data.
// After jpeg_start_decompress() we have the correct scaled output image dimensions available, as well as the output colormap if we asked for color quantization.
// In this example, we need to make an output work buffer of the right size.
// JSAMPLEs per row in output buffer
row_stride = cinfo.output_width * cinfo.output_components;
// Make a one-row-high sample array that will go away when done with image
buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
// Step 6: while (scan lines remain to be read) jpeg_read_scanlines(...);
// Resize output image:
out.configure(ivec2(cinfo.output_width,cinfo.output_height), egami::colorType::RGB8);
uint8_t* dataOutPointer = (uint8_t*)out.getTextureDataPointer();
// Here we use the library's state variable cinfo.output_scanline as the loop counter, so that we don't have to keep track ourselves.
int32_t yyy = 0;
while (cinfo.output_scanline < cinfo.output_height) {
// Get a simple line:
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
// Direst push on the output (got output format RGB8)
//uint8_t* tmpp = dataOutPointer + (row_stride*(cinfo.output_height-yyy));
uint8_t* tmpp = dataOutPointer + (row_stride*yyy);
memcpy(tmpp, buffer[0], row_stride);
yyy++;
}
// Step 7: Finish decompression
(void) jpeg_finish_decompress(&cinfo);
// We can ignore the return value since suspension is not possible with the stdio data source.
// Step 8: Release JPEG decompression object
// This is an important step since it will release a good deal of memory.
jpeg_destroy_decompress(&cinfo);
// At this point you may want to check to see whether any corrupt-data warnings occurred (test whether jerr.pub.num_warnings is nonzero).
return out;
}
static etk::Vector<JOCTET> myBuffer;
#define BLOCK_SIZE 16384
void myInitDestination(j_compress_ptr _cinfo) {
myBuffer.resize(BLOCK_SIZE);
_cinfo->dest->next_output_byte = &myBuffer[0];
_cinfo->dest->free_in_buffer = myBuffer.size();
}
boolean myEmptyOutputBuffer(j_compress_ptr _cinfo) {
size_t oldsize = myBuffer.size();
myBuffer.resize(oldsize + BLOCK_SIZE);
_cinfo->dest->next_output_byte = &myBuffer[oldsize];
_cinfo->dest->free_in_buffer = myBuffer.size() - oldsize;
return TRUE;
}
void myTermDestination(j_compress_ptr _cinfo) {
myBuffer.resize(myBuffer.size() - _cinfo->dest->free_in_buffer);
}
bool egami::storeJPG(const etk::Uri& _uri, const egami::Image& _inputImage) {
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return false;
}
if (fileIo->open(etk::io::OpenMode::Write) == false) {
EGAMI_ERROR("Can not open (w) the file : " << _uri);
return false;
}
etk::Vector<uint8_t> allData;
bool ret = storeJPG(allData, _inputImage);
fileIo->writeAll(allData);
fileIo->close();
return ret;
}
/*
* IMAGE DATA FORMATS:
*
* The standard input image format is a rectangular array of pixels, with
* each pixel having the same number of "component" values (color channels).
* Each pixel row is an array of JSAMPLEs (which typically are unsigned chars).
* If you are working with color data, then the color values for each pixel
* must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit
* RGB color.
*
* For this example, we'll assume that this data structure matches the way
* our application has stored the image in memory, so we can just pass a
* pointer to our image buffer. In particular, let's say that the image is
* RGB color and is described by:
*/
//int quality = 250;
int quality = 200;
bool egami::storeJPG(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage) {
_buffer.clear();
/* This struct contains the JPEG compression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
* It is possible to have several such structures, representing multiple
* compression/decompression processes, in existence at once. We refer
* to any one struct (and its associated working data) as a "JPEG object".
*/
struct jpeg_compress_struct cinfo;
// We use our private extension JPEG error handler. Note that this struct must live as long as the main JPEG parameter struct, to avoid dangling-pointer problems.
struct my_error_mgr jerr;
/* More stuff */
int row_stride; /* physical row width in image buffer */
/* Step 1: allocate and initialize JPEG compression object */
// We set up the normal JPEG error routines, then override error_exit.
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
/* Now we can initialize the JPEG compression object. */
jpeg_create_compress(&cinfo);
/* Step 2: specify data destination (eg, a file) */
/* Note: steps 2 and 3 can be done in either order. */
/* Here we use the library-supplied code to send compressed data to a
* stdio stream. You can also write your own code to do something else.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to write binary files.
*/
#if 0
FILE * outfile; /* target file */
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
#else
/*
uint8_t* rgba = null;
unsigned long size = 0;
etk::Vector<uint8_t> buffer.
jpeg_mem_dest(jpegdata, &rgba, &size);
if(size > 0) {
buffer.resize(size);
for(ii=0; iii<size; ++iii) {
buffer[iii] = rgba[iii];
}
free(rgba);
rgba = null;
}
*/
jpeg_stdio_dest(&cinfo, null);
if (cinfo.dest == null) {
EGAMI_ERROR("Can not write the destination property callback");
return false;
}
cinfo.dest->init_destination = &myInitDestination;
cinfo.dest->empty_output_buffer = &myEmptyOutputBuffer;
cinfo.dest->term_destination = &myTermDestination;
#endif
// Step 3: set parameters for compression
// First we supply a description of the input image. Four fields of the cinfo struct must be filled in:
cinfo.image_width = _inputImage.getSize().x();
cinfo.image_height = _inputImage.getSize().y();
// # of color components per pixel
cinfo.input_components = getFormatColorSize(_inputImage.getType());
// colorspace of input image
cinfo.in_color_space = JCS_RGB;
/* Now use the library's routine to set default compression parameters.
* (You must set at least cinfo.in_color_space before calling this,
* since the defaults depend on the source color space.)
*/
jpeg_set_defaults(&cinfo);
/* Now you can set any non-default parameters you wish to.
* Here we just illustrate the use of quality (quantization table) scaling:
*/
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
/* Step 4: Start compressor */
/* TRUE ensures that we will write a complete interchange-JPEG file.
* Pass TRUE unless you are very sure of what you're doing.
*/
jpeg_start_compress(&cinfo, TRUE);
/* Step 5: while (scan lines remain to be written) */
/* jpeg_write_scanlines(...); */
uint8_t * dataPointer = (uint8_t*)_inputImage.getTextureDataPointer();
while (cinfo.next_scanline < cinfo.image_height) {
/* jpeg_write_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could pass
* more than one scanline at a time if that's more convenient.
*/
JSAMPROW tmp[1];
tmp[0] = &dataPointer[cinfo.next_scanline * cinfo.image_width * getFormatColorSize(_inputImage.getType())];
(void) jpeg_write_scanlines(&cinfo, tmp, 1);
}
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
/* Step 7: release JPEG compression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_compress(&cinfo);
etk::swap(_buffer, myBuffer);
return true;
}

38
egami/wrapperJPG.hpp Normal file
View File

@ -0,0 +1,38 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <egami/egami.hpp>
namespace egami {
/**
* @breif Load a jpeg file in the image.
* @param[in] _uri Uri of the file.
* @return Read Image.
*/
egami::Image loadJPG(const etk::Uri& _uri);
/**
* @breif Load a jpeg file in the image.
* @param[in] _buffer file Buffer
* @return Read Image.
*/
egami::Image loadJPG(const etk::Vector<uint8_t>& _buffer);
/**
* @breif Store a jpg file in the image.
* @param[in] _uri Uri of the file.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storeJPG(const etk::Uri& _uri, const egami::Image& _inputImage);
/**
* @breif Store a jpg file in the image.
* @param[out] _buffer output file buffer.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storeJPG(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage);
}

17
egami/wrapperJPG2000.cpp Normal file
View File

@ -0,0 +1,17 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etk/types.hpp>
#include <egami/debug.hpp>
#include <egami/Image.hpp>
#include <egami/wrapperJPG2000.hpp>
egami::Image egami::loadJPG2000(const etk::Uri& _uri) {
egami::Image out;
EGAMI_TODO("Read JPEG2000 file");
return out;
}

18
egami/wrapperJPG2000.hpp Normal file
View File

@ -0,0 +1,18 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <egami/egami.hpp>
namespace egami {
/**
* @breif Load a jpeg 2000 file in the image.
* @param[in] _uri Uri of the file.
* @return Read Image.
*/
egami::Image loadJPG2000(const etk::Uri& _uri);
}

View File

@ -1,119 +1,118 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <etk/types.hpp>
#include <egami/debug.hpp>
#include <egami/Image.hpp>
#include <egami/wrapperPNG.hpp>
#include <etk/os/FSNode.hpp>
#include <etk/uri/uri.hpp>
#include <png/png.h>
namespace egami {
class ReaderInstance {
public:
virtual ~ReaderInstance() = default;
virtual void read(png_bytep _data, png_size_t _length) = 0;
virtual void write(png_bytep _data, png_size_t _length) = 0;
virtual void flush() = 0;
};
class ReaderInstancIOInterface : public egami::ReaderInstance {
private:
ememory::SharedPtr<etk::io::Interface> m_data;
public:
ReaderInstancIOInterface(const ememory::SharedPtr<etk::io::Interface>& _data):
m_data(_data) {
}
void read(png_bytep _data, png_size_t _length) override {
m_data->read(_data, 1, _length);
}
void write(png_bytep _data, png_size_t _length) override {
m_data->write(_data, 1, _length);
}
void flush() override {
m_data->flush();
}
};
class ReaderInstanceBuffer : public egami::ReaderInstance {
private:
etk::Vector<uint8_t>& m_data;
int32_t m_offset;
public:
ReaderInstanceBuffer(const etk::Vector<uint8_t>& _data, int32_t _offset):
m_data(const_cast<etk::Vector<uint8_t>&>(_data)),
m_offset(_offset) {
}
ReaderInstanceBuffer(etk::Vector<uint8_t>& _data):
m_data(_data),
m_offset(0) {
}
void read(png_bytep data, png_size_t length) override {
memcpy(data, &m_data[m_offset], length);
m_offset += length;
}
void write(png_bytep _data, png_size_t _length) override {
for (uint32_t iii=0; iii<_length; ++iii) {
m_data.pushBack(_data[iii]);
m_offset++;
}
}
void flush() override {
// nothing to do ...
}
};
}
// we must change the access of the IO of the png lib :
static void local_ReadData(png_structp png_ptr, png_bytep data, png_size_t length) {
etk::FSNode* fileNode = static_cast<etk::FSNode*>(png_get_io_ptr(png_ptr));
if (fileNode != nullptr) {
fileNode->fileRead(data, 1, length);
}
}
/*
static void LocalWriteData(png_structp png_ptr, png_bytep data, png_size_t length)
{
etk::FSNode* fileNode = static_cast<etk::FSNode*>(png_get_io_ptr(png_ptr));
if (NULL!=fileNode) {
fileNode->FileWrite(data, 1, length);
static void local_ReadData(png_structp _pngPtr, png_bytep _data, png_size_t _length) {
egami::ReaderInstance* instance = static_cast<egami::ReaderInstance*>(png_get_io_ptr(_pngPtr));
if (instance != null) {
instance->read(_data, _length);
}
}
static void localFlushData(png_structp png_ptr)
{
etk::FSNode* fileNode = static_cast<etk::FSNode*>(png_get_io_ptr(png_ptr));
if (NULL!=fileNode) {
fileNode->FileFlush();
static void Local_WriteData(png_structp _pngPtr, png_bytep _data, png_size_t _length) {
egami::ReaderInstance* instance = static_cast<egami::ReaderInstance*>(png_get_io_ptr(_pngPtr));
if (instance != null) {
instance->write(_data, _length);
}
}
*/
void user_error_fn(png_structp _pngPtr, png_const_charp _errorMsg) {
static void local_FlushData(png_structp _pngPtr) {
egami::ReaderInstance* instance = static_cast<egami::ReaderInstance*>(png_get_io_ptr(_pngPtr));
if (instance != null) {
instance->flush();
}
}
void userErrorFunction(png_structp _pngPtr, png_const_charp _errorMsg) {
EGAMI_ERROR("libpng error: '" << _errorMsg << "'");
}
void user_warning_fn(png_structp _pngPtr, png_const_charp _warningMsg) {
void userWarningFunction(png_structp _pngPtr, png_const_charp _warningMsg) {
EGAMI_WARNING("libpng warning: '" << _warningMsg << "'");
}
egami::Image egami::loadPNG(const std::string& _inputFile) {
static egami::Image genericLoader(png_structp _pngPtr, png_infop _infoPtr) {
egami::Image out;
etk::FSNode fileName(_inputFile);
if (fileName.exist() == false) {
EGAMI_ERROR("File does not existed='" << fileName << "'");
return out;
}
if(fileName.fileOpenRead() == false) {
EGAMI_ERROR("Can not find the file name='" << fileName << "'");
return out;
}
unsigned char header[8];
png_infop info_ptr;
png_structp png_ptr;
if (fileName.fileRead(header,1,8) != 8) {
EGAMI_ERROR("error loading file header");
fileName.fileClose();
return out;
}
if (png_sig_cmp(header, 0, 8)) {
EGAMI_ERROR("Invalid file :" << fileName);
return out;
}
// PNG read setup
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, user_error_fn, user_warning_fn);
if (png_ptr == nullptr) {
EGAMI_ERROR("Can not Allocate PNG structure");
fileName.fileClose();
return out;
}
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == nullptr) {
EGAMI_ERROR("Can not Allocate PNG info structure");
png_destroy_read_struct(&png_ptr, nullptr, nullptr);
fileName.fileClose();
return out;
}
/*
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR(" Can not set the JUMP buffer adresses");
// Free all of the memory associated with the png_ptr and info_ptr
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
fileName.fileClose();
return false;
}
*/
// overwrite the read and write function :
png_set_read_fn(png_ptr,
&fileName,
&local_ReadData);
/*
png_set_write_fn(png_ptr,
&fileName,
&LocalWriteData,
&localFlushData);
*/
// If we have already read some of the signature
png_set_sig_bytes(png_ptr, 8);
png_set_sig_bytes(_pngPtr, 8);
png_read_info(png_ptr, info_ptr);
png_read_info(_pngPtr, _infoPtr);
png_uint_32 width = 0;
png_uint_32 height = 0;
int bit_depth = 0;
int colorType = 0;
int interlace_type = 0;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &colorType, &interlace_type, nullptr, nullptr);
png_get_IHDR(_pngPtr, _infoPtr, &width, &height, &bit_depth, &colorType, &interlace_type, null, null);
// reallocate the image
EGAMI_VERBOSE("Load PNG image : (" << width << "," << height << ")" );
EGAMI_ERROR("Load PNG image : (" << width << "," << height << ") bitDepth=" << bit_depth << " colorType=" << colorType);
switch (colorType) {
case PNG_COLOR_TYPE_RGBA:
out.configure(ivec2(width,height), egami::colorType::RGBA8);
@ -133,34 +132,34 @@ egami::Image egami::loadPNG(const std::string& _inputFile) {
// Tell libpng to strip 16 bits/color files down to 8 bits/color. Use accurate scaling if it's available, otherwise just chop off the low byte.
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
png_set_scale_16(png_ptr);
png_set_scale_16(_pngPtr);
#else
png_set_strip_16(png_ptr);
png_set_strip_16(_pngPtr);
#endif
// Strip alpha bytes from the input data without combining with the background (not recommended).
//png_set_strip_alpha(png_ptr);
//png_set_strip_alpha(_pngPtr);
// Extract multiple pixels with bit depths of 1, 2, and 4 from a single byte into separate bytes (useful for paletted and grayscale images).
png_set_packing(png_ptr);
png_set_packing(_pngPtr);
// Change the order of packed pixels to least significant bit first (not useful if you are using png_set_packing).
png_set_packswap(png_ptr);
png_set_packswap(_pngPtr);
/* Expand paletted colors into true RGB triplets */
if (colorType == PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(png_ptr);
png_set_palette_to_rgb(_pngPtr);
}
// Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel
if ( colorType == PNG_COLOR_TYPE_GRAY
&& bit_depth < 8) {
png_set_expand_gray_1_2_4_to_8(png_ptr);
png_set_expand_gray_1_2_4_to_8(_pngPtr);
}
// Expand paletted or RGB images with transparency to full alpha channels so the data will be available as RGBA quartets.
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0) {
png_set_tRNS_to_alpha(png_ptr);
if (png_get_valid(_pngPtr, _infoPtr, PNG_INFO_tRNS) != 0) {
png_set_tRNS_to_alpha(_pngPtr);
}
/* Set the background color to draw transparent and alpha images over.
@ -171,35 +170,33 @@ egami::Image egami::loadPNG(const std::string& _inputFile) {
*/
/*
png_color::16 my_background, *image_background;
if (png_get_bKGD(png_ptr, info_ptr, &image_background) != 0) {
png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
if (png_get_bKGD(_pngPtr, _infoPtr, &image_background) != 0) {
png_set_background(_pngPtr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
} else {
png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
png_set_background(_pngPtr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}
*/
/* Optional call to gamma correct and add the background to the palette
* and update info structure. REQUIRED if you are expecting libpng to
* update the palette for you (ie you selected such a transform above).
*/
png_read_update_info(png_ptr, info_ptr);
png_read_update_info(_pngPtr, _infoPtr);
// Allocate the memory to hold the image using the fields of info_ptr.
// Allocate the memory to hold the image using the fields of _infoPtr.
// The easiest way to read the image:
png_bytep row_pointers[height];
/* Clear the pointer array */
for (png_uint_32 row = 0; row < height; row++) {
row_pointers[row] = nullptr;
row_pointers[row] = null;
}
for (png_uint_32 row = 0; row < height; row++) {
row_pointers[row] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
row_pointers[row] = (png_bytep)png_malloc(_pngPtr, png_get_rowbytes(_pngPtr, _infoPtr));
}
EGAMI_DEBUG("Load image: " << _inputFile);
png_read_image(png_ptr, row_pointers);
EGAMI_DEBUG("Load image: " << _inputFile << " DONE");
// Read rest of file, and get additional chunks in info_ptr - REQUIRED
png_read_end(png_ptr, info_ptr);
png_read_image(_pngPtr, row_pointers);
// Read rest of file, and get additional chunks in _infoPtr - REQUIRED
png_read_end(_pngPtr, _infoPtr);
//png_set_expand(png_ptr);
//png_set_expand(_pngPtr);
etk::Color<> tmpColor(0,0,0,0);
switch (colorType) {
@ -252,21 +249,241 @@ egami::Image egami::loadPNG(const std::string& _inputFile) {
}
break;
default:
EGAMI_ERROR("Must be RGB+alpha?/GRAY+alpha? not supported : " << (int64_t)png_get_color_type(png_ptr, info_ptr));
if ((png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_PALETTE) != 0) {
EGAMI_ERROR("Must be RGB+alpha?/GRAY+alpha? not supported : " << (int64_t)png_get_color_type(_pngPtr, _infoPtr));
if ((png_get_color_type(_pngPtr, _infoPtr) & PNG_COLOR_MASK_PALETTE) != 0) {
EGAMI_ERROR(" palette");
}
if ((png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) != 0) {
if ((png_get_color_type(_pngPtr, _infoPtr) & PNG_COLOR_MASK_COLOR) != 0) {
EGAMI_ERROR(" color");
}
if ((png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) != 0) {
if ((png_get_color_type(_pngPtr, _infoPtr) & PNG_COLOR_MASK_ALPHA) != 0) {
EGAMI_ERROR(" Alpha");
}
return egami::Image();
}
fileName.fileClose();
// Clean up after the read, and free any memory allocated - REQUIRED
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
png_destroy_read_struct(&_pngPtr, &_infoPtr, null);
return out;
}
egami::Image egami::loadPNG(const etk::Uri& _uri) {
egami::Image out;
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return out;
}
if (fileIo->open(etk::io::OpenMode::Read) == false) {
EGAMI_ERROR("Can not open (r) the file : " << _uri);
return out;
}
unsigned char header[8];
if (fileIo->read(header,1,8) != 8) {
EGAMI_ERROR("error loading file header");
fileIo->close();
return out;
}
if (png_sig_cmp(header, 0, 8)) {
EGAMI_ERROR("Invalid file :" << _uri);
return out;
}
// PNG read setup
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, userErrorFunction, userWarningFunction);
if (png_ptr == null) {
EGAMI_ERROR("Can not Allocate PNG structure");
fileIo->close();
return out;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == null) {
EGAMI_ERROR("Can not Allocate PNG info structure");
png_destroy_read_struct(&png_ptr, null, null);
fileIo->close();
return out;
}
/*
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR(" Can not set the JUMP buffer adresses");
// Free all of the memory associated with the png_ptr and info_ptr
png_destroy_read_struct(&png_ptr, &info_ptr, null);
fileIo->close();
return false;
}
*/
ReaderInstancIOInterface tmpNode(fileIo);
ReaderInstance* tmpPoiter = &tmpNode;
// overwrite the read function:
png_set_read_fn(png_ptr,
tmpPoiter,
&local_ReadData);
out = genericLoader(png_ptr, info_ptr);
fileIo->close();
return out;
}
egami::Image egami::loadPNG(const etk::Vector<uint8_t>& _buffer) {
egami::Image out;
if (png_sig_cmp(&_buffer[0], 0, 8)) {
EGAMI_ERROR("Invalid start buffer:");
return out;
}
// PNG read setup
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, null, userErrorFunction, userWarningFunction);
if (png_ptr == null) {
EGAMI_ERROR("Can not Allocate PNG structure");
return out;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == null) {
EGAMI_ERROR("Can not Allocate PNG info structure");
png_destroy_read_struct(&png_ptr, null, null);
return out;
}
egami::ReaderInstanceBuffer tmpNode(_buffer, 8);
egami::ReaderInstance* tmpPoiter = &tmpNode;
// Overwrite the read function:
png_set_read_fn(png_ptr,
tmpPoiter,
&local_ReadData);
out = genericLoader(png_ptr, info_ptr);
return out;
}
bool genericWriter(png_structp png_ptr, png_infop info_ptr, const egami::Image& _inputImage) {
//png_init_io(png_ptr, fp);
/* write header */
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error jump setting");
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
png_byte bitDepth = 8;
png_byte colorType = 0;
switch(_inputImage.getType()) {
case egami::colorType::RGBA8:
colorType = PNG_COLOR_TYPE_RGB_ALPHA;
//bitDepth = 4;
break;
case egami::colorType::RGB8:
colorType = PNG_COLOR_TYPE_RGB;
//bitDepth = 3;
break;
default:
EGAMI_ERROR("PNG can not export an image with other type than RGB and RGBA request:" << _inputImage.getType());
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
png_set_IHDR(png_ptr,
info_ptr,
_inputImage.getSize().x(),
_inputImage.getSize().y(),
bitDepth,
colorType,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
/* write bytes */
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error while writing byte");
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
etk::Vector<png_bytep> rowPointers;
rowPointers.resize(_inputImage.getSize().y(), NULL);
uint8_t* imageData = (uint8_t*)_inputImage.getTextureDataPointer();
for (size_t iii=0; iii<rowPointers.size(); ++iii) {
rowPointers[iii] = &imageData[_inputImage.getSize().x()*getFormatColorSize(_inputImage.getType())*iii];
}
png_write_image(png_ptr, &rowPointers[0]);
/* end write */
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error while writing byte");
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
png_write_end(png_ptr, NULL);
png_destroy_write_struct(&png_ptr, &info_ptr);
return true;
}
bool egami::storePNG(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage) {
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, userErrorFunction, userWarningFunction);
if (png_ptr == null) {
EGAMI_ERROR("Can not Allocate PNG structure");
return false;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == null) {
EGAMI_ERROR("Can not Allocate PNG info structure");
png_destroy_write_struct(&png_ptr, null);
return false;
}
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error during init_io");
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
egami::ReaderInstanceBuffer tmpNode(_buffer);
egami::ReaderInstance* tmpPointer = &tmpNode;
// overwrite the write functions:
png_set_write_fn(png_ptr,
tmpPointer,
&Local_WriteData,
&local_FlushData);
return genericWriter(png_ptr, info_ptr, _inputImage);
}
bool egami::storePNG(const etk::Uri& _uri, const egami::Image& _inputImage) {
auto fileIo = etk::uri::get(_uri);
if (fileIo == null) {
EGAMI_ERROR("Can not create the uri: " << _uri);
return false;
}
if (fileIo->open(etk::io::OpenMode::Write) == false) {
EGAMI_ERROR("Can not open (w) the file : " << _uri);
return false;
}
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, userErrorFunction, userWarningFunction);
if (png_ptr == null) {
EGAMI_ERROR("Can not Allocate PNG structure");
fileIo->close();
return false;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == null) {
EGAMI_ERROR("Can not Allocate PNG info structure");
png_destroy_write_struct(&png_ptr, null);
fileIo->close();
return false;
}
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error during init_io");
png_destroy_write_struct(&png_ptr, &info_ptr);
fileIo->close();
return false;
}
ReaderInstancIOInterface tmpNode(fileIo);
ReaderInstance* tmpPoiter = &tmpNode;
// overwrite the write functions:
png_set_write_fn(png_ptr,
tmpPoiter,
&Local_WriteData,
&local_FlushData);
bool out = genericWriter(png_ptr, info_ptr, _inputImage);
fileIo->close();
return out;
}

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once
@ -10,9 +10,29 @@
namespace egami {
/**
* @breif Load a png file in the image.
* @param[in] _fileName Name of the file.
* @param[in] _uri Uri of the file.
* @return Read Image.
*/
egami::Image loadPNG(const std::string& _fileName);
egami::Image loadPNG(const etk::Uri& _uri);
/**
* @breif Load a png file in the image.
* @param[in] _buffer File buffer.
* @return Read Image.
*/
egami::Image loadPNG(const etk::Vector<uint8_t>& _buffer);
/**
* @breif Store a PNG file in the image.
* @param[in] _uri Uri of the file.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storePNG(const etk::Uri& _uri, const egami::Image& _inputImage);
/**
* @breif Store a PNG file in the image.
* @param[out] _buffer output file buffer.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storePNG(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage);
}

View File

@ -1,31 +1,31 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <etk/types.hpp>
#include <egami/debug.hpp>
#include <egami/Image.hpp>
#include <egami/wrapperSVG.hpp>
#include <etk/os/FSNode.hpp>
#include <etk/uri/uri.hpp>
#include <esvg/esvg.hpp>
egami::Image egami::loadSVG(const std::string& _fileName, const ivec2& _size) {
egami::Image egami::loadSVG(const etk::Uri& _uri, const ivec2& _size) {
egami::Image out;
esvg::Document svgDocument;
if (svgDocument.load(_fileName) == false) {
EGAMI_ERROR("Error to load SVG file " << _fileName );
if (svgDocument.load(_uri) == false) {
EGAMI_ERROR("Error to load SVG file " << _uri );
return out;
}
ivec2 imageSize = _size;
#if 0
std::vector<etk::Color<float,4>> svgImage = svgDocument.renderImageFloatRGBA(imageSize);
etk::Vector<etk::Color<float,4>> svgImage = svgDocument.renderImageFloatRGBA(imageSize);
out.configure(imageSize, egami::colorType::RGBAf);
out.set(svgImage, imageSize);
#else
std::vector<etk::Color<uint8_t,4>> svgImage = svgDocument.renderImageU8RGBA(imageSize);
etk::Vector<etk::Color<uint8_t,4>> svgImage = svgDocument.renderImageU8RGBA(imageSize);
out.configure(imageSize, egami::colorType::RGBA8);
out.set(svgImage, imageSize);
#endif

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once
@ -10,10 +10,10 @@
namespace egami {
/**
* @brief Load a svg file in the image.
* @param[in] _fileName Name of the file.
* @param[in] _uri Uri of the file.
* @param[in] _size size of the output image.
* @return Generated image
*/
egami::Image loadSVG(const std::string& _fileName, const ivec2& _size=ivec2(-1,-1));
egami::Image loadSVG(const etk::Uri& _uri, const ivec2& _size=ivec2(-1,-1));
}

17
egami/wrapperTIFF.cpp Normal file
View File

@ -0,0 +1,17 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etk/types.hpp>
#include <egami/debug.hpp>
#include <egami/Image.hpp>
#include <egami/wrapperTIFF.hpp>
egami::Image egami::loadTIFF(const etk::Uri& _uri) {
egami::Image out;
EGAMI_TODO("Read TIFF file");
return out;
}

18
egami/wrapperTIFF.hpp Normal file
View File

@ -0,0 +1,18 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <egami/egami.hpp>
namespace egami {
/**
* @breif Load a tiff file in the image.
* @param[in] _uri Uri of the file.
* @return Read Image.
*/
egami::Image loadTIFF(const etk::Uri& _uri);
}

View File

@ -1,13 +0,0 @@
Copyright egami Edouard DUPIN
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

2
lutinParseSubFolders.txt Normal file
View File

@ -0,0 +1,2 @@
tools/viewer
tools/cutter

View File

@ -1,5 +1,5 @@
#!/usr/bin/python
import lutin.debug as debug
import realog.debug as debug
import lutin.tools as tools
@ -13,7 +13,7 @@ def get_desc():
return "Test software for egami"
def get_licence():
return "APACHE-2"
return "MPL-2"
def get_compagny_type():
return "com"
@ -25,15 +25,16 @@ def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
def configure(target, my_module):
my_module.add_depend(['egami', 'test-debug'])
my_module.add_depend([
'egami',
'test-debug'
])
my_module.add_src_file([
'sample/main.cpp',
'sample/read.cpp',
'sample/write.cpp'
])
my_module.copy_path('sample/read.bmp')
my_module.copy_path('sample/read.svg')
my_module.copy_path('sample/read.png')
my_module.copy_path('data/*')
return True

View File

@ -1,5 +1,5 @@
#!/usr/bin/python
import lutin.debug as debug
import realog.debug as debug
import lutin.tools as tools
@ -13,7 +13,7 @@ def get_desc():
return "Test software for egami"
def get_licence():
return "APACHE-2"
return "MPL-2"
def get_compagny_type():
return "com"
@ -25,11 +25,16 @@ def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
def configure(target, my_module):
my_module.add_depend(['egami', 'gtest', 'test-debug'])
my_module.add_depend([
'egami',
'etest',
'test-debug',
'algue',
])
my_module.add_src_file([
'test/main.cpp'
])
#my_module.add_export_path(tools.get_current_path(__file__))
my_module.copy_path('data/*')
return True

View File

@ -1,5 +1,5 @@
#!/usr/bin/python
import lutin.debug as debug
import realog.debug as debug
import lutin.tools as tools
@ -10,7 +10,7 @@ def get_desc():
return "image generator from multiple image type"
def get_licence():
return "APACHE-2"
return "MPL-2"
def get_compagny_type():
return "com"
@ -31,8 +31,6 @@ def configure(target, my_module):
'egami/ImageMono.cpp',
'egami/egami.cpp',
'egami/debug.cpp',
'egami/wrapperPNG.cpp',
'egami/wrapperSVG.cpp',
'egami/wrapperBMP.cpp',
'egami/wrapperEDF.cpp'
])
@ -43,14 +41,47 @@ def configure(target, my_module):
])
my_module.add_depend([
'etk',
'png',
'esvg',
'edtaa3'
])
my_module.add_flag('c++', [
'-Wno-write-strings',
'-Wall'
])
my_module.add_optionnal_depend(
'png',
["c++", "-DEGAMI_BUILD_PNG"],
src_file=[
'egami/wrapperPNG.cpp',
]
)
my_module.add_optionnal_depend(
'esvg',
["c++", "-DEGAMI_BUILD_ESVG"],
src_file=[
'egami/wrapperSVG.cpp',
]
)
my_module.add_optionnal_depend(
'jpeg',
["c++", "-DEGAMI_BUILD_JPEG"],
src_file=[
'egami/wrapperJPG.cpp',
]
)
my_module.add_optionnal_depend(
'openjpeg',
["c++", "-DEGAMI_BUILD_JPEG2000"],
src_file=[
'egami/wrapperJPG2000.cpp',
]
)
my_module.add_optionnal_depend(
'tiff',
["c++", "-DEGAMI_BUILD_TIFF"],
src_file=[
'egami/wrapperTIFF.cpp',
]
)
my_module.add_path(".")
return True

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <test-debug/debug.hpp>
@ -13,7 +13,7 @@ int main(int argc, const char *argv[]) {
// the only one init for etk:
etk::init(argc, argv);
for (int32_t iii=0; iii<argc ; ++iii) {
std::string data = argv[iii];
etk::String data = argv[iii];
if ( data == "-h"
|| data == "--help") {
TEST_PRINT("Help : ");

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
//! [egami_sample_read_all]
@ -19,29 +19,29 @@ static void readBMP() {
egami::Image image;
//! [egami_sample_declare_image]
//! [egami_sample_read_file_bmp]
image = egami::load("DATA:read.bmp");
image = egami::load("DATA:///read.bmp");
//! [egami_sample_read_file_bmp]
TEST_INFO("image exist (BMP): " << image.exist());
}
static void readSVG() {
//! [egami_sample_read_file_svg]
egami::Image image = egami::load("DATA:read.svg");
egami::Image image = egami::load("DATA:///read.svg");
//! [egami_sample_read_file_svg]
TEST_INFO("image exist (SVG): " << image.exist());
//! [egami_sample_read_file_svg_rescale]
image = egami::load("DATA:read.svg", ivec2(800,600));
image = egami::load("DATA:///read.svg", ivec2(800,600));
//! [egami_sample_read_file_svg_rescale]
TEST_INFO("image exist (SVG-rescale): " << image.exist());
//! [egami_sample_read_file_svg_scale_factor]
// TODO : image = egami::load("DATA:read.svg", 0.5);
// TODO : image = egami::load("DATA:///read.svg", 0.5);
//! [egami_sample_read_file_svg_scale_factor]
TEST_INFO("image exist (SVG-scale): " << image.exist());
}
static void readPNG() {
//! [egami_sample_read_file_png]
egami::Image image = egami::load("DATA:read.png");
egami::Image image = egami::load("DATA:///read_128x128.png");
//! [egami_sample_read_file_png]
TEST_INFO("image exist (PNG): " << image.exist());
}

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
//! [egami_sample_write_all]
@ -13,14 +13,14 @@
static void writeBMP() {
//! [egami_sample_create_image]
// create an empty Image (no type and no inside data)
egami::Image image(ivec2(25,25));
egami::Image image(ivec2(25,25), egami::colorType::RGBA8);
image.set(ivec2(5,5), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
image.set(ivec2(12,15), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
image.set(ivec2(4,9), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
// ...
//! [egami_sample_create_image]
//! [egami_sample_write_file_bmp]
bool ret = egami::store(image, "DATA:read.bmp");
bool ret = egami::store(image, "out/egami_test_write.bmp");
//! [egami_sample_write_file_bmp]
TEST_INFO("image write (BMP): " << ret);
}
@ -30,7 +30,28 @@ static void writeSVG() {
}
static void writePNG() {
TEST_INFO("image write (PNG): Not Avaliiable");
// create an empty Image (no type and no inside data)
egami::Image image(ivec2(25,25), egami::colorType::RGBA8);
image.set(ivec2(5,5), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
image.set(ivec2(12,15), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
image.set(ivec2(4,9), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
// ...
//! [egami_sample_write_file_png]
bool ret = egami::store(image, "out/egami_test_write.png");
//! [egami_sample_write_file_png]
TEST_INFO("image write (PNG): " << ret);
}
static void writeJPG() {
// create an empty Image (no type and no inside data)
egami::Image image(ivec2(25,25), egami::colorType::RGB8);
image.set(ivec2(5,5), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
image.set(ivec2(12,15), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
image.set(ivec2(4,9), etk::Color<>(0x88, 0xFF, 0x00, 0xFF));
// ...
//! [egami_sample_write_file_jpg]
bool ret = egami::store(image, "out/egami_test_write.jpg");
//! [egami_sample_write_file_jpg]
TEST_INFO("image write (JPG): " << ret);
}
@ -38,6 +59,7 @@ void appl::write() {
writeBMP();
writeSVG();
writePNG();
writeJPG();
}
//! [egami_sample_write_all]

View File

@ -1,7 +1,7 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#pragma once

View File

@ -1,26 +1,119 @@
/** @file
* @author Edouard DUPIN
* @copyright 2014, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
* @license MPL v2.0 (see license file)
*/
#include <test-debug/debug.hpp>
#include <etk/etk.hpp>
#include <gtest/gtest.h>
#include <etest/etest.hpp>
#include <egami/egami.hpp>
#include <algue/sha512.hpp>
int main(int argc, const char *argv[]) {
// init Google test :
::testing::InitGoogleTest(&argc, const_cast<char **>(argv));
// init etk log system and file interface:
etk::init(argc, argv);
// Run all test with gtest
etest::init(argc, argv);
// Run all test with etest
return RUN_ALL_TESTS();
}
TEST(TestPng, read) {
// TODO : Do real test ...
EXPECT_EQ(5, 6);
TEST(TestBMP, read_227x149) {
egami::Image image = egami::load("DATA:///read_227x149.bmp");
egami::store(image, "out/read_227x149.bmp.bmp");
// Check if image is loaded
EXPECT_EQ(true, image.exist());
// check image correct size
EXPECT_EQ(ivec2(227,149), image.getSize());
// check image correct type
EXPECT_EQ(egami::colorType::RGB8, image.getType());
// check integrity
etk::String sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y()));
EXPECT_EQ("42dbad7abf1e651da58c9df06521d63a878b5bd0db6e1cbe129db3c9782ce640a6709583ba9e6571d314f39b259321dcc392f98bf4412deb5ce8392566d2bc0f", sha512);
}
TEST(TestBMP, read_128x128) {
egami::Image image = egami::load("DATA:///read_128x128.bmp");
egami::store(image, "out/read_128x128.bmp.bmp");
// Check if image is loaded
EXPECT_EQ(true, image.exist());
// check image correct size
EXPECT_EQ(ivec2(128,128), image.getSize());
// check image correct type
EXPECT_EQ(egami::colorType::RGB8, image.getType());
// check integrity
etk::String sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y()));
EXPECT_EQ("ad09f5e165b4acf576e95e27ccd5fcd4003bcdd66c74b3a543807e5fd85db7a6c11a3bbb811950ba19421b2a71815caa14ea9e6575669114766c3483dcc523f3", sha512);
}
TEST(TestPNG, read_227x149) {
egami::Image image = egami::load("DATA:///read_227x149.png");
egami::store(image, "out/read.png_227x149.bmp");
// Check if image is loaded
EXPECT_EQ(true, image.exist());
// check image correct size
EXPECT_EQ(ivec2(227,149), image.getSize());
// check image correct type
EXPECT_EQ(egami::colorType::RGB8, image.getType());
// check integrity
etk::String sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y()));
EXPECT_EQ("42dbad7abf1e651da58c9df06521d63a878b5bd0db6e1cbe129db3c9782ce640a6709583ba9e6571d314f39b259321dcc392f98bf4412deb5ce8392566d2bc0f", sha512);
}
TEST(TestPNG, read_128x128) {
egami::Image image = egami::load("DATA:///read_128x128.png");
egami::store(image, "out/read_128x128.png.bmp");
// Check if image is loaded
EXPECT_EQ(true, image.exist());
// check image correct size
EXPECT_EQ(ivec2(128,128), image.getSize());
// check image correct type
EXPECT_EQ(egami::colorType::RGB8, image.getType());
// check integrity
etk::String sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y()));
EXPECT_EQ("ad09f5e165b4acf576e95e27ccd5fcd4003bcdd66c74b3a543807e5fd85db7a6c11a3bbb811950ba19421b2a71815caa14ea9e6575669114766c3483dcc523f3", sha512);
}
TEST(TestSVG, read) {
egami::Image image = egami::load("DATA:///read.svg");
egami::store(image, "out/read.svg.bmp");
// Check if image is loaded
EXPECT_EQ(true, image.exist());
// check image correct size
EXPECT_EQ(ivec2(64,64), image.getSize());
// check image correct type
EXPECT_EQ(egami::colorType::RGBA8, image.getType());
// check integrity
etk::String sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y()));
EXPECT_EQ("7975d12caae94e67e85909f26b6dc0672d7e4686808d851b3207be6272b6d0153572cd643eea819c2f4dae9f7837165b4d5b34353da9f847d77afc2701945284", sha512);
}
TEST(TestJPG, read_227x149) {
egami::Image image = egami::load("DATA:///read_227x149.jpg");
egami::store(image, "out/read_227x149.jpg.bmp");
// Check if image is loaded
EXPECT_EQ(true, image.exist());
// check image correct size
EXPECT_EQ(ivec2(227,149), image.getSize());
// check image correct type
EXPECT_EQ(egami::colorType::RGB8, image.getType());
// check integrity
etk::String sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y()));
EXPECT_EQ("ac18fe31c86a18566199829bcea0ede3fc8bcac2c62fb5e8b04259719031605450cc53e3dce5fb197e7c3f13c484d015bdbef94f640b7da40f7c32c2d0f803b8", sha512);
}
TEST(TestJPG, read_128x128) {
egami::Image image = egami::load("DATA:///read_128x128.jpg");
egami::store(image, "out/read_128x128.jpg.bmp");
// Check if image is loaded
EXPECT_EQ(true, image.exist());
// check image correct size
EXPECT_EQ(ivec2(128,128), image.getSize());
// check image correct type
EXPECT_EQ(egami::colorType::RGB8, image.getType());
// check integrity
etk::String sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y()));
EXPECT_EQ("dd521e6b75239ee2492c9b3ae81ef1a5061c5d05588ec04a98db65cc210ec4496ca4bb4c18aa45c591a7283e3ce82c8ec4d2554f36a0ed119918a4be89f2e3e0", sha512);
}

View File

@ -0,0 +1,13 @@
/** @file
* @author Edouard DUPIN
* @copyright 2010, Edouard DUPIN, all right reserved
* @license GPL v3 (see license file)
*/
#include <appl/debug.hpp>
int32_t appl::getLogId() {
static int32_t g_val = elog::registerInstance("egami-cutter");
return g_val;
}

View File

@ -0,0 +1,46 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <elog/log.hpp>
extern "C" {
#include <assert.h>
}
namespace appl {
/**
* @brief Get local id of the library
* @return Unique ID of the library
*/
int32_t getLogId();
};
#define APPL_BASIC(info,data) ELOG_BASE(appl::getLogId(),info,data)
#define APPL_PRINT(data) APPL_BASIC(-1, data)
#define APPL_CRITICAL(data) APPL_BASIC(1, data)
#define APPL_ERROR(data) APPL_BASIC(2, data)
#define APPL_WARNING(data) APPL_BASIC(3, data)
#ifdef DEBUG
#define APPL_INFO(data) APPL_BASIC(4, data)
#define APPL_DEBUG(data) APPL_BASIC(5, data)
#define APPL_VERBOSE(data) APPL_BASIC(6, data)
#define APPL_TODO(data) APPL_BASIC(4, "TODO : " << data)
#else
#define APPL_INFO(data) do { } while(false)
#define APPL_DEBUG(data) do { } while(false)
#define APPL_VERBOSE(data) do { } while(false)
#define APPL_TODO(data) do { } while(false)
#endif
#define APPL_HIDDEN(data) do { } while(false)
#define APPL_ASSERT(cond,data) \
do { \
if (!(cond)) { \
APPL_CRITICAL(data); \
assert(!#cond); \
} \
} while (0)

166
tools/cutter/appl/main.cpp Normal file
View File

@ -0,0 +1,166 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <appl/debug.hpp>
#include <etk/etk.hpp>
#include <egami/egami.hpp>
static void usage(int _retValue = 0) {
APPL_PRINT("Help : ");
APPL_PRINT(" ./xxx [options]");
APPL_PRINT(" -h/--help: Display this help");
APPL_PRINT(" -i/--input: Input of the calculator");
APPL_PRINT(" -o/--output: Output of the calculator");
exit(_retValue);
}
int main(int argc, const char *argv[]) {
// the only one init for etk:
etk::init(argc, argv);
etk::Path input;
etk::Path output;
for (int32_t iii=0; iii<argc ; ++iii) {
etk::String data = argv[iii];
if ( data == "-h"
|| data == "--help") {
usage();
} else if (data.startWith("-i=") == true) {
input = etk::String(data.begin() + 3, data.end());
} else if (data.startWith("--input=") == true) {
input = etk::String(data.begin() + 8, data.end());
} else if (data.startWith("-o=") == true) {
output = etk::String(data.begin() + 3, data.end());
} else if (data.startWith("--output=") == true) {
output = etk::String(data.begin() + 9, data.end());
}
}
if (input == "") {
APPL_ERROR("Missing Input ...");
usage(-1);
}
if (output == "") {
APPL_ERROR("Missing output ...");
usage(-1);
}
APPL_INFO("read [START] " << input);
egami::Image image;
image = egami::load(input);
if (image.exist() == false) {
APPL_ERROR("read [STOP ] ==> an error occured...");
return -2;
}
APPL_INFO("read [STOP ]");
ivec2 middle = image.getSize() / 2;
APPL_INFO("Source Image Size:" << image.getSize());
uint8_t baseValue = 0x40;
// top:
uint_t posTop = 0;
uint_t posBottom = image.getSize().y();
uint_t posLeft = 0;
uint_t posRight = image.getSize().x();
uint_t maxOutOfRange = 3;
for (uint_t yyy=0; yyy<middle.y()-maxOutOfRange; ++yyy) {
bool found = false;
//APPL_DEBUG("Check position:" << yyy);
for (uint_t iii=0; iii<maxOutOfRange; ++iii) {
auto val1 = image.get(ivec2(middle.x(), yyy+iii));
//APPL_VERBOSE("Check value:" << iii << " " << val1);
if ( val1.r() < baseValue
&& val1.g() < baseValue
&& val1.b() < baseValue) {
found = true;
break;
}
}
if (found == true) {
continue;
}
posTop = yyy;
break;
}
APPL_INFO("Clip on TOP:" << posTop);
for (uint_t yyy=image.getSize().y()-1; yyy>=middle.y()+maxOutOfRange; --yyy) {
bool found = false;
//APPL_DEBUG("Check position:" << yyy);
for (uint_t iii=0; iii<maxOutOfRange; ++iii) {
auto val1 = image.get(ivec2(middle.x(), yyy-iii));
//APPL_VERBOSE("Check value:" << iii << " " << val1);
if ( val1.r() < baseValue
&& val1.g() < baseValue
&& val1.b() < baseValue) {
found = true;
break;
}
}
if (found == true) {
continue;
}
posBottom = yyy;
break;
}
APPL_INFO("Clip on BOTTOM:" << posBottom);
for (uint_t xxx=0; xxx<middle.x()-maxOutOfRange; ++xxx) {
bool found = false;
//APPL_DEBUG("Check position:" << yyy);
for (uint_t iii=0; iii<maxOutOfRange; ++iii) {
auto val1 = image.get(ivec2(xxx+iii, middle.y()));
//APPL_VERBOSE("Check value:" << iii << " " << val1);
if ( val1.r() < baseValue
&& val1.g() < baseValue
&& val1.b() < baseValue) {
found = true;
break;
}
}
if (found == true) {
continue;
}
posLeft = xxx;
break;
}
APPL_INFO("Clip on LEFT:" << posLeft);
for (uint_t xxx=image.getSize().x()-1; xxx>=middle.x()+maxOutOfRange; --xxx) {
bool found = false;
//APPL_DEBUG("Check position:" << yyy);
for (uint_t iii=0; iii<maxOutOfRange; ++iii) {
auto val1 = image.get(ivec2(xxx-iii, middle.y()));
//APPL_VERBOSE("Check value:" << iii << " " << val1);
if ( val1.r() < baseValue
&& val1.g() < baseValue
&& val1.b() < baseValue) {
found = true;
break;
}
}
if (found == true) {
continue;
}
posRight = xxx;
break;
}
APPL_INFO("Clip on Right:" << posRight);
image.resize(ivec2(image.getSize().x() - posLeft - (image.getSize().x() - posRight),
image.getSize().y() - posTop - (image.getSize().y() - posBottom)),
ivec2(posLeft, posTop));
APPL_INFO("output Image Size:" << image.getSize());
APPL_INFO("write [START] " << output);
bool ret = egami::store(image, output);
if (ret == false) {
APPL_ERROR("write [STOP ] ==> an error occured...");
return -3;
}
APPL_INFO("write [STOP ]");
return 0;
}

View File

@ -0,0 +1,46 @@
#!/usr/bin/python
import realog.debug as debug
import lutin.tools as tools
import os
def get_type():
return "BINARY"
def get_sub_type():
return "TOOL"
def get_desc():
return "egami simple image cutter (bash tools)"
def get_licence():
return "MPL-2"
def get_compagny_type():
return "com"
def get_compagny_name():
return "atria-soft"
def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
def configure(target, my_module):
# add the file to compile:
my_module.add_src_file([
'appl/debug.cpp',
'appl/main.cpp',
])
my_module.add_depend([
'egami',
])
#my_module.copy_file('data/icon.png','icon.png')
my_module.add_path(".")
return True

View File

@ -0,0 +1,122 @@
/** @file
* @author Edouard DUPIN
* @copyright 2010, Edouard DUPIN, all right reserved
* @license BSD v3 (see license file)
*/
#include <appl/debug.hpp>
#include <appl/MainWindows.hpp>
#include <ewol/widget/Image.hpp>
#include <ewol/context/Context.hpp>
#include <eproperty/Value.hpp>
appl::MainWindows::MainWindows() :
m_idDisplayed(-1) {
APPL_DEBUG("CREATE WINDOWS ... ");
addObjectType("appl::MainWindows");
}
void appl::MainWindows::init() {
ewol::widget::Windows::init();
m_image = ewol::widget::Image::create("src", etk::String("DATA:///icon.png"),
"expand", bvec2(true,true),
"fill", bvec2(true,true));
propertyTitle.set("EVI");
m_image->propertyExpand.set(bvec2(true,true));
m_image->propertyFill.set(bvec2(true,true));
setSubWidget(m_image);
shortCutAdd("F12", "menu:reloade-shader");
signalShortcut.connect(sharedFromThis(), &appl::MainWindows::onCallbackShortCut);
}
void appl::MainWindows::onCallbackShortCut(const etk::String& _value) {
APPL_WARNING("Event from ShortCut : " << _value);
if (_value == "menu:reloade-shader") {
ewol::getContext().getResourcesManager().reLoadResources();
ewol::getContext().forceRedrawAll();
} else {
APPL_ERROR("Event from Menu UNKNOW : '" << _value << "'");
}
}
void appl::MainWindows::setListOfFiles(etk::Vector<etk::Path> _listImages) {
m_listImages = _listImages;
if (m_listImages.size() == 0) {
m_idDisplayed = -1;
m_image->propertySource.set("DATA:///icon.png");
propertyTitle.set("EVI");
} else {
m_idDisplayed = 0;
m_image->propertySource.set(m_listImages[0]);
propertyTitle.set("EVI:" + m_listImages[0].getString());
}
}
bool appl::MainWindows::onEventInput(const ewol::event::Input& _event) {
APPL_WARNING(" EVENT : " << _event);
return true;
}
bool appl::MainWindows::onEventEntry(const ewol::event::Entry& _event) {
if (m_idDisplayed == -1) {
return false;
}
if (_event.getStatus() == gale::key::status::down) {
if ( ( _event.getType() == gale::key::keyboard::character
&& _event.getChar() == ' ')
|| _event.getType() == gale::key::keyboard::right) {
m_idDisplayed++;
if (m_idDisplayed >= m_listImages.size()) {
m_idDisplayed--;
return true;
}
m_image->propertySource.set(m_listImages[m_idDisplayed]);
propertyTitle.set("EVI:" + m_listImages[m_idDisplayed].getString() + " " + etk::toString(m_idDisplayed+1) + "/" + etk::toString(m_listImages.size()));
return true;
}
if (_event.getType() == gale::key::keyboard::left) {
m_idDisplayed--;
if (m_idDisplayed < 0) {
m_idDisplayed++;
return true;
}
m_image->propertySource.set(m_listImages[m_idDisplayed]);
propertyTitle.set("EVI:" + m_listImages[m_idDisplayed].getString() + " " + etk::toString(m_idDisplayed+1) + "/" + etk::toString(m_listImages.size()));
return true;
}
if (_event.getType() == gale::key::keyboard::down) {
m_idDisplayed += 10;
if (m_idDisplayed >= m_listImages.size()) {
m_idDisplayed = m_listImages.size()-1;
}
m_image->propertySource.set(m_listImages[m_idDisplayed]);
propertyTitle.set("EVI:" + m_listImages[m_idDisplayed].getString() + " " + etk::toString(m_idDisplayed+1) + "/" + etk::toString(m_listImages.size()));
return true;
}
if (_event.getType() == gale::key::keyboard::up) {
m_idDisplayed -= 10;
if (m_idDisplayed < 0) {
m_idDisplayed = 0;
}
m_image->propertySource.set(m_listImages[m_idDisplayed]);
propertyTitle.set("EVI:" + m_listImages[m_idDisplayed].getString() + " " + etk::toString(m_idDisplayed+1) + "/" + etk::toString(m_listImages.size()));
return true;
}
if (_event.getType() == gale::key::keyboard::pageDown) {
m_idDisplayed = m_listImages.size()-1;
m_image->propertySource.set(m_listImages[m_idDisplayed]);
propertyTitle.set("EVI:" + m_listImages[m_idDisplayed].getString() + " " + etk::toString(m_idDisplayed+1) + "/" + etk::toString(m_listImages.size()));
return true;
}
if (_event.getType() == gale::key::keyboard::pageUp) {
m_idDisplayed = 0;
m_image->propertySource.set(m_listImages[m_idDisplayed]);
propertyTitle.set("EVI:" + m_listImages[m_idDisplayed].getString() + " " + etk::toString(m_idDisplayed+1) + "/" + etk::toString(m_listImages.size()));
return true;
}
}
return true;
}

View File

@ -0,0 +1,33 @@
/** @file
* @author Edouard DUPIN
* @copyright 2010, Edouard DUPIN, all right reserved
* @license BSD v3 (see license file)
*/
#pragma once
#include <appl/debug.hpp>
#include <ewol/widget/Widget.hpp>
#include <ewol/widget/Windows.hpp>
#include <ewol/widget/Image.hpp>
namespace appl {
class MainWindows : public ewol::widget::Windows {
private:
ewol::widget::ImageShared m_image;
etk::Vector<etk::Path> m_listImages;
int64_t m_idDisplayed;
public:
// Constructeur
MainWindows();
void init() override;
public:
DECLARE_FACTORY(MainWindows);
~MainWindows() {};
void setListOfFiles(etk::Vector<etk::Path> _listImages);
protected:
void onCallbackShortCut(const etk::String& _value);
bool onEventInput(const ewol::event::Input& _event) override;
bool onEventEntry(const ewol::event::Entry& _event) override;
};
};

View File

@ -0,0 +1,13 @@
/** @file
* @author Edouard DUPIN
* @copyright 2010, Edouard DUPIN, all right reserved
* @license GPL v3 (see license file)
*/
#include <appl/debug.hpp>
int32_t appl::getLogId() {
static int32_t g_val = elog::registerInstance("egami-viewer");
return g_val;
}

View File

@ -0,0 +1,46 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <elog/log.hpp>
extern "C" {
#include <assert.h>
}
namespace appl {
/**
* @brief Get local id of the library
* @return Unique ID of the library
*/
int32_t getLogId();
};
#define APPL_BASIC(info,data) ELOG_BASE(appl::getLogId(),info,data)
#define APPL_PRINT(data) APPL_BASIC(-1, data)
#define APPL_CRITICAL(data) APPL_BASIC(1, data)
#define APPL_ERROR(data) APPL_BASIC(2, data)
#define APPL_WARNING(data) APPL_BASIC(3, data)
#ifdef DEBUG
#define APPL_INFO(data) APPL_BASIC(4, data)
#define APPL_DEBUG(data) APPL_BASIC(5, data)
#define APPL_VERBOSE(data) APPL_BASIC(6, data)
#define APPL_TODO(data) APPL_BASIC(4, "TODO : " << data)
#else
#define APPL_INFO(data) do { } while(false)
#define APPL_DEBUG(data) do { } while(false)
#define APPL_VERBOSE(data) do { } while(false)
#define APPL_TODO(data) do { } while(false)
#endif
#define APPL_HIDDEN(data) do { } while(false)
#define APPL_ASSERT(cond,data) \
do { \
if (!(cond)) { \
APPL_CRITICAL(data); \
assert(!#cond); \
} \
} while (0)

114
tools/viewer/appl/init.cpp Normal file
View File

@ -0,0 +1,114 @@
/** @file
* @author Edouard DUPIN
* @copyright 2010, Edouard DUPIN, all right reserved
* @license BSD v3 (see license file)
*/
#include <etk/types.hpp>
#include <etk/types.hpp>
#include <etk/theme/theme.hpp>
#include <etk/path/fileSystem.hpp>
#include <ewol/ewol.hpp>
#include <ewol/object/Object.hpp>
#include <ewol/context/Context.hpp>
#include <ewol/widget/Manager.hpp>
#include <appl/debug.hpp>
#include <appl/MainWindows.hpp>
namespace appl {
class MainApplication : public ewol::context::Application {
private:
etk::Vector<etk::Path> m_listFiles;
public:
virtual void onCreate(ewol::Context& _context) {
APPL_INFO(" == > CREATE ... (START) [" << gale::getBoardType() << "] (" << gale::getCompilationMode() << ") (BEGIN)");
for( int32_t iii=0 ; iii<_context.getCmd().size(); iii++) {
etk::String tmpppp = _context.getCmd().get(iii);
if ( tmpppp == "-h"
|| tmpppp == "--help") {
APPL_INFO(" -t c-flags-file-name" );
APPL_INFO(" -h/--help display this help" );
exit(0);
}
if ( tmpppp.size()>=2
&& tmpppp[0] == '-'
&& tmpppp[1] == '-') {
continue;
}
// TODO : Check if it is a path ...
if (etk::path::exist(tmpppp) == false) {
APPL_ERROR("element does not exist: '" << tmpppp << "' ==> rejected");
} else {
if (etk::path::isFile(tmpppp) == true) {
m_listFiles.pushBack(tmpppp);
} else {
etk::Vector<etk::Path> list = etk::path::list(tmpppp, etk::path::LIST_FILE);
for (auto &it : list) {
m_listFiles.pushBack(it);
}
}
}
}
//etk::theme::setName("COLOR", "color/black/");
etk::theme::setName("COLOR", "color/white/");
_context.setSize(vec2(800, 600));
_context.setTitle("egami-viewer");
// select internal data for font ...
_context.getFontDefault().setUseExternal(true);
#ifdef __TARGET_OS__Android
_context.getFontDefault().set("FreeSerif", 19);
#else
_context.getFontDefault().set("FreeSerif;DejaVuSansMono",14);
#endif
// set the application icon ...
_context.setIcon("DATA:///icon.png");
APPL_INFO("==> CREATE ... (END)");
}
void onStart(ewol::Context& _context) {
APPL_INFO("==> START ... (BEGIN)");
ememory::SharedPtr<appl::MainWindows> basicWindows = appl::MainWindows::create();
if (basicWindows == null) {
APPL_ERROR("Can not allocate the basic windows");
return;
}
basicWindows->setListOfFiles(m_listFiles);
// create the specific windows
_context.setWindows(basicWindows);
if (basicWindows == null) {
APPL_ERROR("Can not allocate the basic windows");
_context.exit(-1);
return;
}
// create the specific windows
_context.setWindows(basicWindows);
APPL_INFO("==> START ... (END)");
return;
}
void onStop(ewol::Context& _context) {
APPL_INFO("==> STOP ... (START)");
APPL_INFO("==> STOP ... (END)");
}
};
}
/**
* @brief Main of the program (This can be set in every case, but it is not used in Andoid...).
* @param std IO
* @return std IO
*/
int main(int _argc, const char *_argv[]) {
return ewol::run(ETK_NEW(appl::MainApplication), _argc, _argv);
}

BIN
tools/viewer/data/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,61 @@
#!/usr/bin/python
import realog.debug as debug
import lutin.tools as tools
import os
def get_type():
return "BINARY"
def get_sub_type():
return "TOOL"
def get_desc():
return "egami simple image viewer (visual)"
def get_licence():
return "MPL-2"
def get_compagny_type():
return "com"
def get_compagny_name():
return "atria-soft"
def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
def configure(target, my_module):
# add the file to compile:
my_module.add_src_file([
'appl/debug.cpp',
'appl/init.cpp',
'appl/MainWindows.cpp',
])
my_module.add_depend(['ewol'])
my_module.copy_file('data/icon.png','icon.png')
my_module.add_path(".")
"""
# set the package properties :
my_module.pkg_set("VERSION", versionID)
my_module.pkg_set("COMPAGNY_TYPE", "org")
my_module.pkg_set("COMPAGNY_NAME", "Edouard DUPIN")
my_module.pkg_set("MAINTAINER", ["Mr DUPIN Edouard <yui.heero@gmail.com>"])
my_module.pkg_set("ICON", tools.get_current_path(__file__) + "/../data/icon.png")
my_module.pkg_set("SECTION", ["Development"])
my_module.pkg_set("PRIORITY", "optional")
my_module.pkg_set("DESCRIPTION", "ewol test software")
my_module.pkg_set("NAME", "test software")
my_module.pkg_add("RIGHT", "SET_ORIENTATION")
my_module.pkg_add("RIGHT", "VIBRATE")
"""
return True

View File

@ -1 +1 @@
0.5.0
1.0.0