Compare commits
32 Commits
6ac1e14bcf
...
bc85e51774
Author | SHA1 | Date | |
---|---|---|---|
bc85e51774 | |||
7d89856b1f | |||
0bcfe53bc9 | |||
aa9610f85d | |||
437e6b3c18 | |||
c8863cde93 | |||
41a2c25992 | |||
37c83f9728 | |||
8ef121b698 | |||
8779e2011a | |||
f2dbed233f | |||
10be74f158 | |||
861f59061f | |||
fc67e46de5 | |||
99eae9d10f | |||
7965135796 | |||
024d00adff | |||
c171d4a035 | |||
eb5618aaac | |||
55c71b8ed9 | |||
e790937d29 | |||
1181bc52e7 | |||
f345c9c664 | |||
b0eea46065 | |||
b790073cab | |||
db0bbb781f | |||
2205f2ef8d | |||
130aeac190 | |||
e628bba94f | |||
2d8af2d99c | |||
25e6b83253 | |||
927604ad6d |
373
LICENSE
Normal 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.
|
@ -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
@ -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
After Width: | Height: | Size: 5.0 KiB |
BIN
data/read3.jpg
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
data/read4.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
data/read_128x128.bmp
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
data/read_128x128.jpg
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
data/read_128x128.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
data/read_227x149.bmp
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
data/read_227x149.jpg
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
data/read_227x149.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
data/read_228x149.bmp
Normal file
After Width: | Height: | Size: 100 KiB |
@ -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,
|
||||
|
241
egami/Image.cpp
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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() {
|
||||
|
@ -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());
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
239
egami/egami.cpp
@ -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 << "'");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
@ -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
@ -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
@ -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
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
@ -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);
|
||||
}
|
||||
|
13
license.txt
@ -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
@ -0,0 +1,2 @@
|
||||
tools/viewer
|
||||
tools/cutter
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 : ");
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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
|
||||
|
115
test/main.cpp
@ -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);
|
||||
}
|
||||
|
13
tools/cutter/appl/debug.cpp
Normal 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;
|
||||
}
|
46
tools/cutter/appl/debug.hpp
Normal 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
@ -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;
|
||||
}
|
46
tools/cutter/lutin_egami-cutter.py
Executable 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
|
||||
|
||||
|
||||
|
||||
|
122
tools/viewer/appl/MainWindows.cpp
Normal 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;
|
||||
}
|
33
tools/viewer/appl/MainWindows.hpp
Normal 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;
|
||||
};
|
||||
};
|
||||
|
||||
|
13
tools/viewer/appl/debug.cpp
Normal 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;
|
||||
}
|
46
tools/viewer/appl/debug.hpp
Normal 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
@ -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
After Width: | Height: | Size: 13 KiB |
61
tools/viewer/lutin_egami-viewer.py
Executable 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
|
||||
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
0.5.0
|
||||
1.0.0
|