first commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
# Enforce LF for Netpbm formats on Windows
|
||||
testdata/test.pam text eol=lf
|
||||
testdata/test.pbm text eol=lf
|
||||
testdata/test.pfm text eol=lf
|
||||
testdata/test.pgm text eol=lf
|
||||
testdata/test.ppm text eol=lf
|
||||
@@ -0,0 +1,661 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
@@ -0,0 +1,71 @@
|
||||
## go-fitz
|
||||
|
||||
### Maal Disclaimer
|
||||
This is just fork from github repository. Forked in order to recompile with new glibc version.
|
||||
|
||||
Whenever you have problem with compability you can download source package from [Mupdf source](https://mupdf.com/downloads/archive/mupdf-1.23.0-source.tar.gz) after simply run ``` make``` to compile on your platform. When this is completed just simply copy following files:
|
||||
|
||||
```libmupdf.a``` ==> ```libs/libmupdfthird_linux_amd64.a```
|
||||
```libmupdf-third.a``` ==> ```libs/libmupdf_linux_amd64.a```
|
||||
|
||||
Part of file name 'linux_amd64' maens OS and platform.
|
||||
##### Notice that you need to compile MuPdf source for OS and platform you want to use
|
||||
|
||||
### ---------------------------------------------------------------------------------------
|
||||
|
||||
Go wrapper for [MuPDF](http://mupdf.com/) fitz library that can extract pages from PDF and EPUB documents as images, text, html or svg.
|
||||
|
||||
### Build tags
|
||||
|
||||
* `extlib` - use external MuPDF library
|
||||
* `static` - build with static external MuPDF library (used with `extlib`)
|
||||
* `pkgconfig` - enable pkg-config (used with `extlib`)
|
||||
* `musl` - use musl compiled library
|
||||
|
||||
### Example
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/jpeg"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gen2brain/go-fitz"
|
||||
)
|
||||
|
||||
func main() {
|
||||
doc, err := fitz.New("test.pdf")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
tmpDir, err := os.MkdirTemp(os.TempDir(), "fitz")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Extract pages as images
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
img, err := doc.Image(n)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.jpg", n)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = jpeg.Encode(f, img, &jpeg.Options{jpeg.DefaultQuality})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
```
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package fitz_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/jpeg"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.ma-al.com/go-fitz"
|
||||
)
|
||||
|
||||
func ExampleNew() {
|
||||
doc, err := fitz.New("test.pdf")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
tmpDir, err := os.MkdirTemp(os.TempDir(), "fitz")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Extract pages as images
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
img, err := doc.Image(n)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.jpg", n)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = jpeg.Encode(f, img, &jpeg.Options{Quality: jpeg.DefaultQuality})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
|
||||
// Extract pages as text
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
text, err := doc.Text(n)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.txt", n)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = f.WriteString(text)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
|
||||
// Extract pages as html
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
html, err := doc.HTML(n, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.html", n)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = f.WriteString(html)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
|
||||
// Extract pages as svg
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
svg, err := doc.SVG(n)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.svg", n)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = f.WriteString(svg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,559 @@
|
||||
// Package fitz provides wrapper for the [MuPDF](http://mupdf.com/) fitz library
|
||||
// that can extract pages from PDF and EPUB documents as images, text, html or svg.
|
||||
package fitz
|
||||
|
||||
/*
|
||||
#include <mupdf/fitz.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const char *fz_version = FZ_VERSION;
|
||||
|
||||
fz_document *open_document(fz_context *ctx, const char *filename) {
|
||||
fz_document *doc;
|
||||
|
||||
fz_try(ctx) {
|
||||
doc = fz_open_document(ctx, filename);
|
||||
}
|
||||
fz_catch(ctx) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
fz_document *open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream) {
|
||||
fz_document *doc;
|
||||
|
||||
fz_try(ctx) {
|
||||
doc = fz_open_document_with_stream(ctx, magic, stream);
|
||||
}
|
||||
fz_catch(ctx) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"image"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Errors.
|
||||
var (
|
||||
ErrNoSuchFile = errors.New("fitz: no such file")
|
||||
ErrCreateContext = errors.New("fitz: cannot create context")
|
||||
ErrOpenDocument = errors.New("fitz: cannot open document")
|
||||
ErrOpenMemory = errors.New("fitz: cannot open memory")
|
||||
ErrPageMissing = errors.New("fitz: page missing")
|
||||
ErrCreatePixmap = errors.New("fitz: cannot create pixmap")
|
||||
ErrPixmapSamples = errors.New("fitz: cannot get pixmap samples")
|
||||
ErrNeedsPassword = errors.New("fitz: document needs password")
|
||||
ErrLoadOutline = errors.New("fitz: cannot load outline")
|
||||
)
|
||||
|
||||
// Document represents fitz document.
|
||||
type Document struct {
|
||||
ctx *C.struct_fz_context
|
||||
data []byte // binds data to the Document lifecycle avoiding premature GC
|
||||
doc *C.struct_fz_document
|
||||
mtx sync.Mutex
|
||||
stream *C.fz_stream
|
||||
}
|
||||
|
||||
// Outline type.
|
||||
type Outline struct {
|
||||
// Hierarchy level of the entry (starting from 1).
|
||||
Level int
|
||||
// Title of outline item.
|
||||
Title string
|
||||
// Destination in the document to be displayed when this outline item is activated.
|
||||
URI string
|
||||
// The page number of an internal link.
|
||||
Page int
|
||||
// Top.
|
||||
Top float64
|
||||
}
|
||||
|
||||
// Link type.
|
||||
type Link struct {
|
||||
URI string
|
||||
}
|
||||
|
||||
// New returns new fitz document.
|
||||
func New(filename string) (f *Document, err error) {
|
||||
f = &Document{}
|
||||
|
||||
filename, err = filepath.Abs(filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, e := os.Stat(filename); e != nil {
|
||||
err = ErrNoSuchFile
|
||||
return
|
||||
}
|
||||
|
||||
f.ctx = (*C.struct_fz_context)(unsafe.Pointer(C.fz_new_context_imp(nil, nil, C.FZ_STORE_UNLIMITED, C.fz_version)))
|
||||
if f.ctx == nil {
|
||||
err = ErrCreateContext
|
||||
return
|
||||
}
|
||||
|
||||
C.fz_register_document_handlers(f.ctx)
|
||||
|
||||
cfilename := C.CString(filename)
|
||||
defer C.free(unsafe.Pointer(cfilename))
|
||||
|
||||
f.doc = C.open_document(f.ctx, cfilename)
|
||||
if f.doc == nil {
|
||||
err = ErrOpenDocument
|
||||
return
|
||||
}
|
||||
|
||||
ret := C.fz_needs_password(f.ctx, f.doc)
|
||||
v := int(ret) != 0
|
||||
if v {
|
||||
err = ErrNeedsPassword
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// NewFromMemory returns new fitz document from byte slice.
|
||||
func NewFromMemory(b []byte) (f *Document, err error) {
|
||||
f = &Document{}
|
||||
|
||||
f.ctx = (*C.struct_fz_context)(unsafe.Pointer(C.fz_new_context_imp(nil, nil, C.FZ_STORE_UNLIMITED, C.fz_version)))
|
||||
if f.ctx == nil {
|
||||
err = ErrCreateContext
|
||||
return
|
||||
}
|
||||
|
||||
C.fz_register_document_handlers(f.ctx)
|
||||
|
||||
stream := C.fz_open_memory(f.ctx, (*C.uchar)(&b[0]), C.size_t(len(b)))
|
||||
f.stream = C.fz_keep_stream(f.ctx, stream)
|
||||
|
||||
if f.stream == nil {
|
||||
err = ErrOpenMemory
|
||||
return
|
||||
}
|
||||
|
||||
magic := contentType(b)
|
||||
if magic == "" {
|
||||
err = ErrOpenMemory
|
||||
return
|
||||
}
|
||||
|
||||
f.data = b
|
||||
|
||||
cmagic := C.CString(magic)
|
||||
defer C.free(unsafe.Pointer(cmagic))
|
||||
|
||||
f.doc = C.open_document_with_stream(f.ctx, cmagic, f.stream)
|
||||
if f.doc == nil {
|
||||
err = ErrOpenDocument
|
||||
}
|
||||
|
||||
ret := C.fz_needs_password(f.ctx, f.doc)
|
||||
v := int(ret) != 0
|
||||
if v {
|
||||
err = ErrNeedsPassword
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// NewFromReader returns new fitz document from io.Reader.
|
||||
func NewFromReader(r io.Reader) (f *Document, err error) {
|
||||
b, e := io.ReadAll(r)
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
|
||||
f, err = NewFromMemory(b)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// NumPage returns total number of pages in document.
|
||||
func (f *Document) NumPage() int {
|
||||
return int(C.fz_count_pages(f.ctx, f.doc))
|
||||
}
|
||||
|
||||
// Image returns image for given page number.
|
||||
func (f *Document) Image(pageNumber int) (image.Image, error) {
|
||||
return f.ImageDPI(pageNumber, 300.0)
|
||||
}
|
||||
|
||||
// ImageDPI returns image for given page number and DPI.
|
||||
func (f *Document) ImageDPI(pageNumber int, dpi float64) (image.Image, error) {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
|
||||
img := image.RGBA{}
|
||||
|
||||
if pageNumber >= f.NumPage() {
|
||||
return nil, ErrPageMissing
|
||||
}
|
||||
|
||||
page := C.fz_load_page(f.ctx, f.doc, C.int(pageNumber))
|
||||
defer C.fz_drop_page(f.ctx, page)
|
||||
|
||||
var bounds C.fz_rect
|
||||
bounds = C.fz_bound_page(f.ctx, page)
|
||||
|
||||
var ctm C.fz_matrix
|
||||
ctm = C.fz_scale(C.float(dpi/72), C.float(dpi/72))
|
||||
|
||||
var bbox C.fz_irect
|
||||
bounds = C.fz_transform_rect(bounds, ctm)
|
||||
bbox = C.fz_round_rect(bounds)
|
||||
|
||||
pixmap := C.fz_new_pixmap_with_bbox(f.ctx, C.fz_device_rgb(f.ctx), bbox, nil, 1)
|
||||
if pixmap == nil {
|
||||
return nil, ErrCreatePixmap
|
||||
}
|
||||
|
||||
C.fz_clear_pixmap_with_value(f.ctx, pixmap, C.int(0xff))
|
||||
//defer C.fz_drop_pixmap(f.ctx, pixmap)
|
||||
|
||||
device := C.fz_new_draw_device(f.ctx, ctm, pixmap)
|
||||
C.fz_enable_device_hints(f.ctx, device, C.FZ_NO_CACHE)
|
||||
defer C.fz_drop_device(f.ctx, device)
|
||||
|
||||
drawMatrix := C.fz_identity
|
||||
C.fz_run_page(f.ctx, page, device, drawMatrix, nil)
|
||||
|
||||
C.fz_close_device(f.ctx, device)
|
||||
|
||||
pixels := C.fz_pixmap_samples(f.ctx, pixmap)
|
||||
if pixels == nil {
|
||||
return nil, ErrPixmapSamples
|
||||
}
|
||||
defer C.free(unsafe.Pointer(pixels))
|
||||
|
||||
img.Pix = C.GoBytes(unsafe.Pointer(pixels), C.int(4*bbox.x1*bbox.y1))
|
||||
img.Rect = image.Rect(int(bbox.x0), int(bbox.y0), int(bbox.x1), int(bbox.y1))
|
||||
img.Stride = 4 * img.Rect.Max.X
|
||||
|
||||
return &img, nil
|
||||
}
|
||||
|
||||
// ImagePNG returns image for given page number as PNG bytes.
|
||||
func (f *Document) ImagePNG(pageNumber int, dpi float64) ([]byte, error) {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
|
||||
if pageNumber >= f.NumPage() {
|
||||
return nil, ErrPageMissing
|
||||
}
|
||||
|
||||
page := C.fz_load_page(f.ctx, f.doc, C.int(pageNumber))
|
||||
defer C.fz_drop_page(f.ctx, page)
|
||||
|
||||
var bounds C.fz_rect
|
||||
bounds = C.fz_bound_page(f.ctx, page)
|
||||
|
||||
var ctm C.fz_matrix
|
||||
ctm = C.fz_scale(C.float(dpi/72), C.float(dpi/72))
|
||||
|
||||
var bbox C.fz_irect
|
||||
bounds = C.fz_transform_rect(bounds, ctm)
|
||||
bbox = C.fz_round_rect(bounds)
|
||||
|
||||
pixmap := C.fz_new_pixmap_with_bbox(f.ctx, C.fz_device_rgb(f.ctx), bbox, nil, 1)
|
||||
if pixmap == nil {
|
||||
return nil, ErrCreatePixmap
|
||||
}
|
||||
|
||||
C.fz_clear_pixmap_with_value(f.ctx, pixmap, C.int(0xff))
|
||||
//defer C.fz_drop_pixmap(f.ctx, pixmap)
|
||||
|
||||
device := C.fz_new_draw_device(f.ctx, ctm, pixmap)
|
||||
C.fz_enable_device_hints(f.ctx, device, C.FZ_NO_CACHE)
|
||||
defer C.fz_drop_device(f.ctx, device)
|
||||
|
||||
drawMatrix := C.fz_identity
|
||||
C.fz_run_page(f.ctx, page, device, drawMatrix, nil)
|
||||
|
||||
C.fz_close_device(f.ctx, device)
|
||||
|
||||
buf := C.fz_new_buffer_from_pixmap_as_png(f.ctx, pixmap, C.fz_default_color_params)
|
||||
defer C.fz_drop_buffer(f.ctx, buf)
|
||||
|
||||
size := C.fz_buffer_storage(f.ctx, buf, nil)
|
||||
str := C.GoStringN(C.fz_string_from_buffer(f.ctx, buf), C.int(size))
|
||||
|
||||
return []byte(str), nil
|
||||
}
|
||||
|
||||
// Links returns slice of links for given page number.
|
||||
func (f *Document) Links(pageNumber int) ([]Link, error) {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
|
||||
if pageNumber >= f.NumPage() {
|
||||
return nil, ErrPageMissing
|
||||
}
|
||||
|
||||
page := C.fz_load_page(f.ctx, f.doc, C.int(pageNumber))
|
||||
defer C.fz_drop_page(f.ctx, page)
|
||||
|
||||
links := C.fz_load_links(f.ctx, page)
|
||||
defer C.fz_drop_link(f.ctx, links)
|
||||
|
||||
linkCount := 0
|
||||
for currLink := links; currLink != nil; currLink = currLink.next {
|
||||
linkCount++
|
||||
}
|
||||
|
||||
if linkCount == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
gLinks := make([]Link, linkCount)
|
||||
|
||||
currLink := links
|
||||
for i := 0; i < linkCount; i++ {
|
||||
gLinks[i] = Link{
|
||||
URI: C.GoString(currLink.uri),
|
||||
}
|
||||
currLink = currLink.next
|
||||
}
|
||||
|
||||
return gLinks, nil
|
||||
}
|
||||
|
||||
// Text returns text for given page number.
|
||||
func (f *Document) Text(pageNumber int) (string, error) {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
|
||||
if pageNumber >= f.NumPage() {
|
||||
return "", ErrPageMissing
|
||||
}
|
||||
|
||||
page := C.fz_load_page(f.ctx, f.doc, C.int(pageNumber))
|
||||
defer C.fz_drop_page(f.ctx, page)
|
||||
|
||||
var bounds C.fz_rect
|
||||
bounds = C.fz_bound_page(f.ctx, page)
|
||||
|
||||
var ctm C.fz_matrix
|
||||
ctm = C.fz_scale(C.float(72.0/72), C.float(72.0/72))
|
||||
|
||||
text := C.fz_new_stext_page(f.ctx, bounds)
|
||||
defer C.fz_drop_stext_page(f.ctx, text)
|
||||
|
||||
var opts C.fz_stext_options
|
||||
opts.flags = 0
|
||||
|
||||
device := C.fz_new_stext_device(f.ctx, text, &opts)
|
||||
C.fz_enable_device_hints(f.ctx, device, C.FZ_NO_CACHE)
|
||||
defer C.fz_drop_device(f.ctx, device)
|
||||
|
||||
var cookie C.fz_cookie
|
||||
C.fz_run_page(f.ctx, page, device, ctm, &cookie)
|
||||
|
||||
C.fz_close_device(f.ctx, device)
|
||||
|
||||
buf := C.fz_new_buffer_from_stext_page(f.ctx, text)
|
||||
defer C.fz_drop_buffer(f.ctx, buf)
|
||||
|
||||
str := C.GoString(C.fz_string_from_buffer(f.ctx, buf))
|
||||
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// HTML returns html for given page number.
|
||||
func (f *Document) HTML(pageNumber int, header bool) (string, error) {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
|
||||
if pageNumber >= f.NumPage() {
|
||||
return "", ErrPageMissing
|
||||
}
|
||||
|
||||
page := C.fz_load_page(f.ctx, f.doc, C.int(pageNumber))
|
||||
defer C.fz_drop_page(f.ctx, page)
|
||||
|
||||
var bounds C.fz_rect
|
||||
bounds = C.fz_bound_page(f.ctx, page)
|
||||
|
||||
var ctm C.fz_matrix
|
||||
ctm = C.fz_scale(C.float(72.0/72), C.float(72.0/72))
|
||||
|
||||
text := C.fz_new_stext_page(f.ctx, bounds)
|
||||
defer C.fz_drop_stext_page(f.ctx, text)
|
||||
|
||||
var opts C.fz_stext_options
|
||||
opts.flags = C.FZ_STEXT_PRESERVE_IMAGES
|
||||
|
||||
device := C.fz_new_stext_device(f.ctx, text, &opts)
|
||||
C.fz_enable_device_hints(f.ctx, device, C.FZ_NO_CACHE)
|
||||
defer C.fz_drop_device(f.ctx, device)
|
||||
|
||||
var cookie C.fz_cookie
|
||||
C.fz_run_page(f.ctx, page, device, ctm, &cookie)
|
||||
|
||||
C.fz_close_device(f.ctx, device)
|
||||
|
||||
buf := C.fz_new_buffer(f.ctx, 1024)
|
||||
defer C.fz_drop_buffer(f.ctx, buf)
|
||||
|
||||
out := C.fz_new_output_with_buffer(f.ctx, buf)
|
||||
defer C.fz_drop_output(f.ctx, out)
|
||||
|
||||
if header {
|
||||
C.fz_print_stext_header_as_html(f.ctx, out)
|
||||
}
|
||||
C.fz_print_stext_page_as_html(f.ctx, out, text, C.int(pageNumber))
|
||||
if header {
|
||||
C.fz_print_stext_trailer_as_html(f.ctx, out)
|
||||
}
|
||||
|
||||
str := C.GoString(C.fz_string_from_buffer(f.ctx, buf))
|
||||
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// SVG returns svg document for given page number.
|
||||
func (f *Document) SVG(pageNumber int) (string, error) {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
|
||||
if pageNumber >= f.NumPage() {
|
||||
return "", ErrPageMissing
|
||||
}
|
||||
|
||||
page := C.fz_load_page(f.ctx, f.doc, C.int(pageNumber))
|
||||
defer C.fz_drop_page(f.ctx, page)
|
||||
|
||||
var bounds C.fz_rect
|
||||
bounds = C.fz_bound_page(f.ctx, page)
|
||||
|
||||
var ctm C.fz_matrix
|
||||
ctm = C.fz_scale(C.float(72.0/72), C.float(72.0/72))
|
||||
bounds = C.fz_transform_rect(bounds, ctm)
|
||||
|
||||
buf := C.fz_new_buffer(f.ctx, 1024)
|
||||
defer C.fz_drop_buffer(f.ctx, buf)
|
||||
|
||||
out := C.fz_new_output_with_buffer(f.ctx, buf)
|
||||
defer C.fz_drop_output(f.ctx, out)
|
||||
|
||||
device := C.fz_new_svg_device(f.ctx, out, bounds.x1-bounds.x0, bounds.y1-bounds.y0, C.FZ_SVG_TEXT_AS_PATH, 1)
|
||||
C.fz_enable_device_hints(f.ctx, device, C.FZ_NO_CACHE)
|
||||
defer C.fz_drop_device(f.ctx, device)
|
||||
|
||||
var cookie C.fz_cookie
|
||||
C.fz_run_page(f.ctx, page, device, ctm, &cookie)
|
||||
|
||||
C.fz_close_device(f.ctx, device)
|
||||
|
||||
str := C.GoString(C.fz_string_from_buffer(f.ctx, buf))
|
||||
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// ToC returns the table of contents (also known as outline).
|
||||
func (f *Document) ToC() ([]Outline, error) {
|
||||
data := make([]Outline, 0)
|
||||
|
||||
outline := C.fz_load_outline(f.ctx, f.doc)
|
||||
if outline == nil {
|
||||
return nil, ErrLoadOutline
|
||||
}
|
||||
defer C.fz_drop_outline(f.ctx, outline)
|
||||
|
||||
var walk func(outline *C.fz_outline, level int)
|
||||
|
||||
walk = func(outline *C.fz_outline, level int) {
|
||||
for outline != nil {
|
||||
res := Outline{}
|
||||
res.Level = level
|
||||
res.Title = C.GoString(outline.title)
|
||||
res.URI = C.GoString(outline.uri)
|
||||
res.Page = int(outline.page.page)
|
||||
res.Top = float64(outline.y)
|
||||
data = append(data, res)
|
||||
|
||||
if outline.down != nil {
|
||||
walk(outline.down, level+1)
|
||||
}
|
||||
outline = outline.next
|
||||
}
|
||||
}
|
||||
|
||||
walk(outline, 1)
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Metadata returns the map with standard metadata.
|
||||
func (f *Document) Metadata() map[string]string {
|
||||
data := make(map[string]string)
|
||||
|
||||
lookup := func(key string) string {
|
||||
ckey := C.CString(key)
|
||||
defer C.free(unsafe.Pointer(ckey))
|
||||
|
||||
buf := make([]byte, 256)
|
||||
C.fz_lookup_metadata(f.ctx, f.doc, ckey, (*C.char)(unsafe.Pointer(&buf[0])), C.int(len(buf)))
|
||||
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
data["format"] = lookup("format")
|
||||
data["encryption"] = lookup("encryption")
|
||||
data["title"] = lookup("info:Title")
|
||||
data["author"] = lookup("info:Author")
|
||||
data["subject"] = lookup("info:Subject")
|
||||
data["keywords"] = lookup("info:Keywords")
|
||||
data["creator"] = lookup("info:Creator")
|
||||
data["producer"] = lookup("info:Producer")
|
||||
data["creationDate"] = lookup("info:CreationDate")
|
||||
data["modDate"] = lookup("info:modDate")
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// Bound gives the Bounds of a given Page in the document.
|
||||
func (f *Document) Bound(pageNumber int) (image.Rectangle, error) {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
|
||||
if pageNumber >= f.NumPage() {
|
||||
return image.Rectangle{}, ErrPageMissing
|
||||
}
|
||||
|
||||
page := C.fz_load_page(f.ctx, f.doc, C.int(pageNumber))
|
||||
defer C.fz_drop_page(f.ctx, page)
|
||||
|
||||
var bounds C.fz_rect
|
||||
bounds = C.fz_bound_page(f.ctx, page)
|
||||
return image.Rect(int(bounds.x0), int(bounds.y0), int(bounds.x1), int(bounds.y1)), nil
|
||||
}
|
||||
|
||||
// Close closes the underlying fitz document.
|
||||
func (f *Document) Close() error {
|
||||
if f.stream != nil {
|
||||
C.fz_drop_stream(f.ctx, f.stream)
|
||||
}
|
||||
|
||||
C.fz_drop_document(f.ctx, f.doc)
|
||||
C.fz_drop_context(f.ctx)
|
||||
|
||||
f.data = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
//go:build !extlib
|
||||
|
||||
package fitz
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -Iinclude
|
||||
|
||||
#cgo linux,386 LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_386 -lmupdfthird_linux_386 -lm
|
||||
#cgo linux,amd64,!musl LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_amd64 -lmupdfthird_linux_amd64 -lm
|
||||
#cgo linux,amd64,musl LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_amd64_musl -lmupdfthird_linux_amd64_musl -lm
|
||||
#cgo linux,!android,arm LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_arm -lmupdfthird_linux_arm -lm
|
||||
#cgo linux,!android,arm64,!musl LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_arm64 -lmupdfthird_linux_arm64 -lm
|
||||
#cgo linux,!android,arm64,musl LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_arm64_musl -lmupdfthird_linux_arm64_musl -lm
|
||||
#cgo android,arm LDFLAGS: -L${SRCDIR}/libs -lmupdf_android_arm -lmupdfthird_android_arm -lm -llog
|
||||
#cgo android,arm64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_android_arm64 -lmupdfthird_android_arm64 -lm -llog
|
||||
#cgo windows,386 LDFLAGS: -L${SRCDIR}/libs -lmupdf_windows_386 -lmupdfthird_windows_386 -lm -lcomdlg32 -lgdi32 -lmsvcr90 -Wl,--allow-multiple-definition
|
||||
#cgo windows,amd64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_windows_amd64 -lmupdfthird_windows_amd64 -lm -lcomdlg32 -lgdi32 -Wl,--allow-multiple-definition
|
||||
#cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_darwin_amd64 -lmupdfthird_darwin_amd64 -lm
|
||||
#cgo darwin,arm64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_darwin_arm64 -lmupdfthird_darwin_arm64 -lm
|
||||
*/
|
||||
import "C"
|
||||
@@ -0,0 +1,11 @@
|
||||
//go:build extlib && !pkgconfig
|
||||
|
||||
package fitz
|
||||
|
||||
/*
|
||||
#cgo !static LDFLAGS: -lmupdf -lm
|
||||
#cgo static LDFLAGS: -lmupdf -lm -lmupdf-third
|
||||
#cgo android LDFLAGS: -llog
|
||||
#cgo windows LDFLAGS: -lcomdlg32 -lgdi32
|
||||
*/
|
||||
import "C"
|
||||
@@ -0,0 +1,8 @@
|
||||
//go:build extlib && pkgconfig
|
||||
|
||||
package fitz
|
||||
|
||||
/*
|
||||
#cgo pkg-config: mupdf
|
||||
*/
|
||||
import "C"
|
||||
@@ -0,0 +1,171 @@
|
||||
package fitz
|
||||
|
||||
// contentType returns document MIME type.
|
||||
func contentType(b []byte) string {
|
||||
l := len(b)
|
||||
// for file length shortcuts see https://github.com/mathiasbynens/small
|
||||
switch {
|
||||
case l < 8:
|
||||
return ""
|
||||
case isPAM(b):
|
||||
return "image/x-portable-arbitrarymap"
|
||||
case isPBM(b):
|
||||
return "image/x-portable-bitmap"
|
||||
case isPFM(b):
|
||||
return "image/x-portable-floatmap"
|
||||
case isPGM(b):
|
||||
return "image/x-portable-greymap"
|
||||
case isPPM(b):
|
||||
return "image/x-portable-pixmap"
|
||||
case isGIF(b):
|
||||
return "image/gif"
|
||||
case l < 16:
|
||||
return ""
|
||||
case isBMP(b):
|
||||
return "image/bmp"
|
||||
case isJBIG2(b):
|
||||
// file header + segment header = 24 bytes
|
||||
return "image/x-jb2"
|
||||
case l < 32:
|
||||
return ""
|
||||
case isTIFF(b):
|
||||
return "image/tiff"
|
||||
case l < 64:
|
||||
return ""
|
||||
case isJPEG(b):
|
||||
return "image/jpeg"
|
||||
case isPNG(b):
|
||||
return "image/png"
|
||||
case isJPEG2000(b):
|
||||
return "image/jp2"
|
||||
case isJPEGXR(b):
|
||||
return "image/vnd.ms-photo"
|
||||
case isPDF(b):
|
||||
return "application/pdf"
|
||||
case isZIP(b):
|
||||
switch {
|
||||
case isEPUB(b):
|
||||
return "application/epub+zip"
|
||||
case isXPS(b):
|
||||
return "application/oxps"
|
||||
default:
|
||||
// fitz will consider it a Comic Book Archive
|
||||
// must contain at least one image, i.e. >64 bytes
|
||||
return "application/zip"
|
||||
}
|
||||
case isXML(b):
|
||||
// fitz will consider it an FB2
|
||||
// minimal valid FB2 w/o content is >64 bytes
|
||||
return "text/xml"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func isBMP(b []byte) bool {
|
||||
return b[0] == 0x42 && b[1] == 0x4D
|
||||
}
|
||||
|
||||
func isGIF(b []byte) bool {
|
||||
return b[0] == 0x47 && b[1] == 0x49 && b[2] == 0x46 && b[3] == 0x38
|
||||
}
|
||||
|
||||
func isJBIG2(b []byte) bool {
|
||||
return b[0] == 0x97 && b[1] == 0x4A && b[2] == 0x42 && b[3] == 0x32 &&
|
||||
b[4] == 0x0D && b[5] == 0x0A && b[6] == 0x1A && b[7] == 0x0A
|
||||
}
|
||||
|
||||
func isJPEG(b []byte) bool {
|
||||
return b[0] == 0xFF && b[1] == 0xD8 && b[2] == 0xFF
|
||||
}
|
||||
|
||||
func isJPEG2000(b []byte) bool {
|
||||
switch {
|
||||
case b[0] == 0xFF && b[1] == 0x4F && b[2] == 0xFF && b[3] == 0x51:
|
||||
return true
|
||||
default:
|
||||
return b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x0C &&
|
||||
b[4] == 0x6A && b[5] == 0x50 && b[6] == 0x20 && b[7] == 0x20 &&
|
||||
b[8] == 0x0D && b[9] == 0x0A && b[10] == 0x87 && b[11] == 0x0A
|
||||
}
|
||||
}
|
||||
|
||||
func isJPEGXR(b []byte) bool {
|
||||
return b[0] == 0x49 && b[1] == 0x49 && b[2] == 0xBC
|
||||
}
|
||||
|
||||
func isPAM(b []byte) bool {
|
||||
return b[0] == 0x50 && b[1] == 0x37 && b[2] == 0x0A
|
||||
}
|
||||
|
||||
func isPBM(b []byte) bool {
|
||||
return b[0] == 0x50 && (b[1] == 0x31 || b[1] == 0x34) && b[2] == 0x0A
|
||||
}
|
||||
|
||||
func isPFM(b []byte) bool {
|
||||
return b[0] == 0x50 && (b[1] == 0x46 || b[1] == 0x66) && b[2] == 0x0A
|
||||
}
|
||||
|
||||
func isPGM(b []byte) bool {
|
||||
return b[0] == 0x50 && (b[1] == 0x32 || b[1] == 0x35) && b[2] == 0x0A
|
||||
}
|
||||
|
||||
func isPPM(b []byte) bool {
|
||||
return b[0] == 0x50 && (b[1] == 0x33 || b[1] == 0x36) && b[2] == 0x0A
|
||||
}
|
||||
|
||||
func isPNG(b []byte) bool {
|
||||
return b[0] == 0x89 && b[1] == 0x50 && b[2] == 0x4E && b[3] == 0x47 &&
|
||||
b[4] == 0x0D && b[5] == 0x0A && b[6] == 0x1A && b[7] == 0x0A
|
||||
}
|
||||
|
||||
func isTIFF(b []byte) bool {
|
||||
return b[0] == 0x49 && b[1] == 0x49 && b[2] == 0x2A && b[3] == 0x00 ||
|
||||
b[0] == 0x4D && b[1] == 0x4D && b[2] == 0x00 && b[3] == 0x2A
|
||||
}
|
||||
|
||||
// PDF magic number 25 50 44 46 = "%PDF".
|
||||
func isPDF(b []byte) bool {
|
||||
return b[0] == 0x25 && b[1] == 0x50 && b[2] == 0x44 && b[3] == 0x46
|
||||
}
|
||||
|
||||
// Non-empty ZIP archive magic number 50 4B 03 04.
|
||||
func isZIP(b []byte) bool {
|
||||
return b[0] == 0x50 && b[1] == 0x4B && b[2] == 0x03 && b[3] == 0x04
|
||||
}
|
||||
|
||||
// Looks for a file named "mimetype" containing the ASCII string "application/epub+zip".
|
||||
// The file must be uncompressed and be the first file within the archive.
|
||||
func isEPUB(b []byte) bool {
|
||||
return b[30] == 0x6D && b[31] == 0x69 && b[32] == 0x6D && b[33] == 0x65 &&
|
||||
b[34] == 0x74 && b[35] == 0x79 && b[36] == 0x70 && b[37] == 0x65 &&
|
||||
b[38] == 0x61 && b[39] == 0x70 && b[40] == 0x70 && b[41] == 0x6C &&
|
||||
b[42] == 0x69 && b[43] == 0x63 && b[44] == 0x61 && b[45] == 0x74 &&
|
||||
b[46] == 0x69 && b[47] == 0x6F && b[48] == 0x6E && b[49] == 0x2F &&
|
||||
b[50] == 0x65 && b[51] == 0x70 && b[52] == 0x75 && b[53] == 0x62 &&
|
||||
b[54] == 0x2B && b[55] == 0x7A && b[56] == 0x69 && b[57] == 0x70
|
||||
}
|
||||
|
||||
// Looks for a file named "[Content_Types].xml" at the root of a ZIP archive.
|
||||
// MS Office apps put this file first within the archive enabling for fast detection.
|
||||
func isXPS(b []byte) bool {
|
||||
return b[30] == 0x5B && b[31] == 0x43 && b[32] == 0x6F && b[33] == 0x6E &&
|
||||
b[34] == 0x74 && b[35] == 0x65 && b[36] == 0x6E && b[37] == 0x74 &&
|
||||
b[38] == 0x5F && b[39] == 0x54 && b[40] == 0x79 && b[41] == 0x70 &&
|
||||
b[42] == 0x65 && b[43] == 0x73 && b[44] == 0x5D && b[45] == 0x2E &&
|
||||
b[46] == 0x78 && b[47] == 0x6D && b[48] == 0x6C
|
||||
}
|
||||
|
||||
// Checks for "<?xml" string at the beginning of the file.
|
||||
// Possible occurrences of a UTF-8 BOM are also considered.
|
||||
func isXML(b []byte) bool {
|
||||
switch {
|
||||
// w/o UTF-8 BOM:
|
||||
case b[0] == 0x3C && b[1] == 0x3F && b[2] == 0x78 && b[3] == 0x6D && b[4] == 0x6C:
|
||||
return true
|
||||
// w/ UTF-8 BOM:
|
||||
default:
|
||||
return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF && b[3] == 0x3C &&
|
||||
b[4] == 0x3F && b[5] == 0x78 && b[6] == 0x6D && b[7] == 0x6C
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package fitz
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testContentType(want string, b []byte, t *testing.T) {
|
||||
if got := contentType(b); got != want {
|
||||
t.Errorf("contentType([]byte) = '%v'; want '%v'", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
//go:embed testdata/test.bmp
|
||||
var bmp []byte
|
||||
|
||||
func TestContentTypeBMP(t *testing.T) {
|
||||
testContentType("image/bmp", bmp, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.epub
|
||||
var epub []byte
|
||||
|
||||
func TestContentTypeEPUB(t *testing.T) {
|
||||
testContentType("application/epub+zip", epub, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.cbz
|
||||
var cbz []byte
|
||||
|
||||
func TestContentTypeCBZ(t *testing.T) {
|
||||
testContentType("application/zip", cbz, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.fb2
|
||||
var fb2 []byte
|
||||
|
||||
func TestContentTypeFB2(t *testing.T) {
|
||||
testContentType("text/xml", fb2, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.gif
|
||||
var gif []byte
|
||||
|
||||
func TestContentTypeGIF(t *testing.T) {
|
||||
testContentType("image/gif", gif, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.jb2
|
||||
var jb2 []byte
|
||||
|
||||
func TestContentTypeJBIG2(t *testing.T) {
|
||||
testContentType("image/x-jb2", jb2, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.jpg
|
||||
var jpg []byte
|
||||
|
||||
func TestContentTypeJPEG(t *testing.T) {
|
||||
testContentType("image/jpeg", jpg, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.jp2
|
||||
var jp2 []byte
|
||||
|
||||
func TestContentTypeJPEG2000(t *testing.T) {
|
||||
testContentType("image/jp2", jp2, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.jxr
|
||||
var jxr []byte
|
||||
|
||||
func TestContentTypeJPEGXR(t *testing.T) {
|
||||
testContentType("image/vnd.ms-photo", jxr, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.pam
|
||||
var pam []byte
|
||||
|
||||
func TestContentTypePAM(t *testing.T) {
|
||||
testContentType("image/x-portable-arbitrarymap", pam, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.pbm
|
||||
var pbm []byte
|
||||
|
||||
func TestContentTypePBM(t *testing.T) {
|
||||
testContentType("image/x-portable-bitmap", pbm, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.pdf
|
||||
var pdf []byte
|
||||
|
||||
func TestContentTypePDF(t *testing.T) {
|
||||
testContentType("application/pdf", pdf, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.pfm
|
||||
var pfm []byte
|
||||
|
||||
func TestContentTypePFM(t *testing.T) {
|
||||
testContentType("image/x-portable-floatmap", pfm, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.pgm
|
||||
var pgm []byte
|
||||
|
||||
func TestContentTypePGM(t *testing.T) {
|
||||
testContentType("image/x-portable-greymap", pgm, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.ppm
|
||||
var ppm []byte
|
||||
|
||||
func TestContentTypePPM(t *testing.T) {
|
||||
testContentType("image/x-portable-pixmap", ppm, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.tif
|
||||
var tif []byte
|
||||
|
||||
func TestContentTypeTIFF(t *testing.T) {
|
||||
testContentType("image/tiff", tif, t)
|
||||
}
|
||||
|
||||
//go:embed testdata/test.xps
|
||||
var xps []byte
|
||||
|
||||
func TestContentTypeXPS(t *testing.T) {
|
||||
testContentType("application/oxps", xps, t)
|
||||
}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
package fitz_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.ma-al.com/go-fitz"
|
||||
)
|
||||
|
||||
func TestImage(t *testing.T) {
|
||||
doc, err := fitz.New(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
tmpDir, err := os.MkdirTemp(os.TempDir(), "fitz")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
img, err := doc.Image(n)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.jpg", n)))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = jpeg.Encode(f, img, &jpeg.Options{Quality: jpeg.DefaultQuality})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageFromMemory(t *testing.T) {
|
||||
b, err := os.ReadFile(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
doc, err := fitz.NewFromMemory(b)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
tmpDir, err := os.MkdirTemp(os.TempDir(), "fitz")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
img, err := doc.Image(n)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.jpg", n)))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = jpeg.Encode(f, img, &jpeg.Options{Quality: jpeg.DefaultQuality})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinks(t *testing.T) {
|
||||
doc, err := fitz.New(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
links, err := doc.Links(2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if len(links) != 1 {
|
||||
t.Error("expected 1 link, got", len(links))
|
||||
}
|
||||
|
||||
if links[0].URI != "https://creativecommons.org/licenses/by-nc-sa/4.0/" {
|
||||
t.Error("expected empty URI, got", links[0].URI)
|
||||
}
|
||||
}
|
||||
|
||||
func TestText(t *testing.T) {
|
||||
doc, err := fitz.New(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
tmpDir, err := os.MkdirTemp(os.TempDir(), "fitz")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
text, err := doc.Text(n)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.txt", n)))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = f.WriteString(text)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTML(t *testing.T) {
|
||||
doc, err := fitz.New(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
tmpDir, err := ioutil.TempDir(os.TempDir(), "fitz")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
html, err := doc.HTML(n, true)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.html", n)))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = f.WriteString(html)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestSVG(t *testing.T) {
|
||||
doc, err := fitz.New(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
tmpDir, err := ioutil.TempDir(os.TempDir(), "fitz")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
for n := 0; n < doc.NumPage(); n++ {
|
||||
svg, err := doc.SVG(n)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.svg", n)))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = f.WriteString(svg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestToC(t *testing.T) {
|
||||
doc, err := fitz.New(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
_, err = doc.ToC()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadata(t *testing.T) {
|
||||
doc, err := fitz.New(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
|
||||
meta := doc.Metadata()
|
||||
if len(meta) == 0 {
|
||||
t.Error(fmt.Errorf("metadata is empty"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBound(t *testing.T) {
|
||||
doc, err := fitz.New(filepath.Join("testdata", "test.pdf"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
defer doc.Close()
|
||||
expected := image.Rect(0, 0, 612, 792)
|
||||
|
||||
for i := 0; i < doc.NumPage(); i++ {
|
||||
bound, err := doc.Bound(i)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if bound != expected {
|
||||
t.Error(fmt.Errorf("bounds didn't match go %v when expedient %v", bound, expected))
|
||||
}
|
||||
}
|
||||
|
||||
_, err = doc.Bound(doc.NumPage())
|
||||
if err != fitz.ErrPageMissing {
|
||||
t.Error(fmt.Errorf("ErrPageMissing not returned got %v", err))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUDPF_FITZ_H
|
||||
#define MUDPF_FITZ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mupdf/fitz/version.h"
|
||||
#include "mupdf/fitz/config.h"
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/output.h"
|
||||
#include "mupdf/fitz/log.h"
|
||||
|
||||
#include "mupdf/fitz/crypt.h"
|
||||
#include "mupdf/fitz/getopt.h"
|
||||
#include "mupdf/fitz/geometry.h"
|
||||
#include "mupdf/fitz/hash.h"
|
||||
#include "mupdf/fitz/pool.h"
|
||||
#include "mupdf/fitz/string-util.h"
|
||||
#include "mupdf/fitz/tree.h"
|
||||
#include "mupdf/fitz/bidi.h"
|
||||
#include "mupdf/fitz/xml.h"
|
||||
|
||||
/* I/O */
|
||||
#include "mupdf/fitz/buffer.h"
|
||||
#include "mupdf/fitz/stream.h"
|
||||
#include "mupdf/fitz/compress.h"
|
||||
#include "mupdf/fitz/compressed-buffer.h"
|
||||
#include "mupdf/fitz/filter.h"
|
||||
#include "mupdf/fitz/archive.h"
|
||||
|
||||
/* Resources */
|
||||
#include "mupdf/fitz/store.h"
|
||||
#include "mupdf/fitz/color.h"
|
||||
#include "mupdf/fitz/pixmap.h"
|
||||
#include "mupdf/fitz/bitmap.h"
|
||||
#include "mupdf/fitz/image.h"
|
||||
#include "mupdf/fitz/shade.h"
|
||||
#include "mupdf/fitz/font.h"
|
||||
#include "mupdf/fitz/path.h"
|
||||
#include "mupdf/fitz/text.h"
|
||||
#include "mupdf/fitz/separation.h"
|
||||
#include "mupdf/fitz/glyph.h"
|
||||
|
||||
#include "mupdf/fitz/device.h"
|
||||
#include "mupdf/fitz/display-list.h"
|
||||
#include "mupdf/fitz/structured-text.h"
|
||||
|
||||
#include "mupdf/fitz/transition.h"
|
||||
#include "mupdf/fitz/glyph-cache.h"
|
||||
|
||||
/* Document */
|
||||
#include "mupdf/fitz/link.h"
|
||||
#include "mupdf/fitz/outline.h"
|
||||
#include "mupdf/fitz/document.h"
|
||||
|
||||
#include "mupdf/fitz/util.h"
|
||||
|
||||
/* Output formats */
|
||||
#include "mupdf/fitz/writer.h"
|
||||
#include "mupdf/fitz/band-writer.h"
|
||||
#include "mupdf/fitz/write-pixmap.h"
|
||||
#include "mupdf/fitz/output-svg.h"
|
||||
|
||||
#include "mupdf/fitz/story.h"
|
||||
#include "mupdf/fitz/story-writer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,373 @@
|
||||
// Copyright (C) 2004-2022 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_ARCHIVE_H
|
||||
#define MUPDF_FITZ_ARCHIVE_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/buffer.h"
|
||||
#include "mupdf/fitz/stream.h"
|
||||
#include "mupdf/fitz/tree.h"
|
||||
|
||||
/* PUBLIC API */
|
||||
|
||||
/**
|
||||
fz_archive:
|
||||
|
||||
fz_archive provides methods for accessing "archive" files.
|
||||
An archive file is a conceptual entity that contains multiple
|
||||
files, which can be counted, enumerated, and read.
|
||||
|
||||
Implementations of fz_archive based upon directories, zip
|
||||
and tar files are included.
|
||||
*/
|
||||
|
||||
typedef struct fz_archive fz_archive;
|
||||
|
||||
/**
|
||||
Open a zip or tar archive
|
||||
|
||||
Open a file and identify its archive type based on the archive
|
||||
signature contained inside.
|
||||
|
||||
filename: a path to a file as it would be given to open(2).
|
||||
*/
|
||||
fz_archive *fz_open_archive(fz_context *ctx, const char *filename);
|
||||
|
||||
/**
|
||||
Open zip or tar archive stream.
|
||||
|
||||
Open an archive using a seekable stream object rather than
|
||||
opening a file or directory on disk.
|
||||
*/
|
||||
fz_archive *fz_open_archive_with_stream(fz_context *ctx, fz_stream *file);
|
||||
|
||||
/**
|
||||
Open zip or tar archive stream.
|
||||
|
||||
Does the same as fz_open_archive_with_stream, but will not throw
|
||||
an error in the event of failing to recognise the format. Will
|
||||
still throw errors in other cases though!
|
||||
*/
|
||||
fz_archive *fz_try_open_archive_with_stream(fz_context *ctx, fz_stream *file);
|
||||
|
||||
/**
|
||||
Open a directory as if it was an archive.
|
||||
|
||||
A special case where a directory is opened as if it was an
|
||||
archive.
|
||||
|
||||
Note that for directories it is not possible to retrieve the
|
||||
number of entries or list the entries. It is however possible
|
||||
to check if the archive has a particular entry.
|
||||
|
||||
path: a path to a directory as it would be given to opendir(3).
|
||||
*/
|
||||
fz_archive *fz_open_directory(fz_context *ctx, const char *path);
|
||||
|
||||
|
||||
/**
|
||||
Determine if a given path is a directory.
|
||||
*/
|
||||
int fz_is_directory(fz_context *ctx, const char *path);
|
||||
|
||||
/**
|
||||
Drop a reference to an archive.
|
||||
|
||||
When the last reference is dropped, this closes and releases
|
||||
any memory or filehandles associated with the archive.
|
||||
*/
|
||||
void fz_drop_archive(fz_context *ctx, fz_archive *arch);
|
||||
|
||||
/**
|
||||
Keep a reference to an archive.
|
||||
*/
|
||||
fz_archive *
|
||||
fz_keep_archive(fz_context *ctx, fz_archive *arch);
|
||||
|
||||
/**
|
||||
Return a pointer to a string describing the format of the
|
||||
archive.
|
||||
|
||||
The lifetime of the string is unspecified (in current
|
||||
implementations the string will persist until the archive
|
||||
is closed, but this is not guaranteed).
|
||||
*/
|
||||
const char *fz_archive_format(fz_context *ctx, fz_archive *arch);
|
||||
|
||||
/**
|
||||
Number of entries in archive.
|
||||
|
||||
Will always return a value >= 0.
|
||||
|
||||
May throw an exception if this type of archive cannot count the
|
||||
entries (such as a directory).
|
||||
*/
|
||||
int fz_count_archive_entries(fz_context *ctx, fz_archive *arch);
|
||||
|
||||
/**
|
||||
Get listed name of entry position idx.
|
||||
|
||||
idx: Must be a value >= 0 < return value from
|
||||
fz_count_archive_entries. If not in range NULL will be
|
||||
returned.
|
||||
|
||||
May throw an exception if this type of archive cannot list the
|
||||
entries (such as a directory).
|
||||
*/
|
||||
const char *fz_list_archive_entry(fz_context *ctx, fz_archive *arch, int idx);
|
||||
|
||||
/**
|
||||
Check if entry by given name exists.
|
||||
|
||||
If named entry does not exist 0 will be returned, if it does
|
||||
exist 1 is returned.
|
||||
|
||||
name: Entry name to look for, this must be an exact match to
|
||||
the entry name in the archive.
|
||||
*/
|
||||
int fz_has_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
|
||||
|
||||
/**
|
||||
Opens an archive entry as a stream.
|
||||
|
||||
name: Entry name to look for, this must be an exact match to
|
||||
the entry name in the archive.
|
||||
|
||||
Throws an exception if a matching entry cannot be found.
|
||||
*/
|
||||
fz_stream *fz_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
|
||||
|
||||
/**
|
||||
Opens an archive entry as a stream.
|
||||
|
||||
Returns NULL if a matching entry cannot be found, otherwise
|
||||
behaves exactly as fz_open_archive_entry.
|
||||
*/
|
||||
fz_stream *fz_try_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
|
||||
|
||||
/**
|
||||
Reads all bytes in an archive entry
|
||||
into a buffer.
|
||||
|
||||
name: Entry name to look for, this must be an exact match to
|
||||
the entry name in the archive.
|
||||
|
||||
Throws an exception if a matching entry cannot be found.
|
||||
*/
|
||||
fz_buffer *fz_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
|
||||
|
||||
/**
|
||||
Reads all bytes in an archive entry
|
||||
into a buffer.
|
||||
|
||||
name: Entry name to look for, this must be an exact match to
|
||||
the entry name in the archive.
|
||||
|
||||
Returns NULL if a matching entry cannot be found. Otherwise behaves
|
||||
the same as fz_read_archive_entry. Exceptions may be thrown.
|
||||
*/
|
||||
fz_buffer *fz_try_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
|
||||
|
||||
/**
|
||||
fz_archive: tar implementation
|
||||
*/
|
||||
|
||||
/**
|
||||
Detect if stream object is a tar achieve.
|
||||
|
||||
Assumes that the stream object is seekable.
|
||||
*/
|
||||
int fz_is_tar_archive(fz_context *ctx, fz_stream *file);
|
||||
|
||||
/**
|
||||
Open a tar archive file.
|
||||
|
||||
An exception is throw if the file is not a tar archive as
|
||||
indicated by the presence of a tar signature.
|
||||
|
||||
filename: a path to a tar archive file as it would be given to
|
||||
open(2).
|
||||
*/
|
||||
fz_archive *fz_open_tar_archive(fz_context *ctx, const char *filename);
|
||||
|
||||
/**
|
||||
Open a tar archive stream.
|
||||
|
||||
Open an archive using a seekable stream object rather than
|
||||
opening a file or directory on disk.
|
||||
|
||||
An exception is throw if the stream is not a tar archive as
|
||||
indicated by the presence of a tar signature.
|
||||
|
||||
*/
|
||||
fz_archive *fz_open_tar_archive_with_stream(fz_context *ctx, fz_stream *file);
|
||||
|
||||
/**
|
||||
fz_archive: zip implementation
|
||||
*/
|
||||
|
||||
/**
|
||||
Detect if stream object is a zip archive.
|
||||
|
||||
Assumes that the stream object is seekable.
|
||||
*/
|
||||
int fz_is_zip_archive(fz_context *ctx, fz_stream *file);
|
||||
|
||||
/**
|
||||
Open a zip archive file.
|
||||
|
||||
An exception is throw if the file is not a zip archive as
|
||||
indicated by the presence of a zip signature.
|
||||
|
||||
filename: a path to a zip archive file as it would be given to
|
||||
open(2).
|
||||
*/
|
||||
fz_archive *fz_open_zip_archive(fz_context *ctx, const char *path);
|
||||
|
||||
/**
|
||||
Open a zip archive stream.
|
||||
|
||||
Open an archive using a seekable stream object rather than
|
||||
opening a file or directory on disk.
|
||||
|
||||
An exception is throw if the stream is not a zip archive as
|
||||
indicated by the presence of a zip signature.
|
||||
|
||||
*/
|
||||
fz_archive *fz_open_zip_archive_with_stream(fz_context *ctx, fz_stream *file);
|
||||
|
||||
/**
|
||||
fz_zip_writer offers methods for creating and writing zip files.
|
||||
It can be seen as the reverse of the fz_archive zip
|
||||
implementation.
|
||||
*/
|
||||
|
||||
typedef struct fz_zip_writer fz_zip_writer;
|
||||
|
||||
/**
|
||||
Create a new zip writer that writes to a given file.
|
||||
|
||||
Open an archive using a seekable stream object rather than
|
||||
opening a file or directory on disk.
|
||||
*/
|
||||
fz_zip_writer *fz_new_zip_writer(fz_context *ctx, const char *filename);
|
||||
|
||||
/**
|
||||
Create a new zip writer that writes to a given output stream.
|
||||
|
||||
Ownership of out passes in immediately upon calling this function.
|
||||
The caller should never drop the fz_output, even if this function throws
|
||||
an exception.
|
||||
*/
|
||||
fz_zip_writer *fz_new_zip_writer_with_output(fz_context *ctx, fz_output *out);
|
||||
|
||||
|
||||
/**
|
||||
Given a buffer of data, (optionally) compress it, and add it to
|
||||
the zip file with the given name.
|
||||
*/
|
||||
void fz_write_zip_entry(fz_context *ctx, fz_zip_writer *zip, const char *name, fz_buffer *buf, int compress);
|
||||
|
||||
/**
|
||||
Close the zip file for writing.
|
||||
|
||||
This flushes any pending data to the file. This can throw
|
||||
exceptions.
|
||||
*/
|
||||
void fz_close_zip_writer(fz_context *ctx, fz_zip_writer *zip);
|
||||
|
||||
/**
|
||||
Drop the reference to the zipfile.
|
||||
|
||||
In common with other 'drop' methods, this will never throw an
|
||||
exception.
|
||||
*/
|
||||
void fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip);
|
||||
|
||||
/**
|
||||
Create an archive that holds named buffers.
|
||||
|
||||
tree can either be a preformed tree with fz_buffers as values,
|
||||
or it can be NULL for an empty tree.
|
||||
*/
|
||||
fz_archive *fz_new_tree_archive(fz_context *ctx, fz_tree *tree);
|
||||
|
||||
/**
|
||||
Add a named buffer to an existing tree archive.
|
||||
|
||||
The tree will take a new reference to the buffer. Ownership
|
||||
is not transferred.
|
||||
*/
|
||||
void fz_tree_archive_add_buffer(fz_context *ctx, fz_archive *arch_, const char *name, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Add a named block of data to an existing tree archive.
|
||||
|
||||
The data will be copied into a buffer, and so the caller
|
||||
may free it as soon as this returns.
|
||||
*/
|
||||
void fz_tree_archive_add_data(fz_context *ctx, fz_archive *arch_, const char *name, const void *data, size_t size);
|
||||
|
||||
/**
|
||||
Create a new multi archive (initially empty).
|
||||
*/
|
||||
fz_archive *fz_new_multi_archive(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Add an archive to the set of archives handled by a multi
|
||||
archive.
|
||||
|
||||
If path is NULL, then the archive contents will appear at the
|
||||
top level, otherwise, the archives contents will appear prefixed
|
||||
by path.
|
||||
*/
|
||||
void fz_mount_multi_archive(fz_context *ctx, fz_archive *arch_, fz_archive *sub, const char *path);
|
||||
|
||||
/**
|
||||
Implementation details: Subject to change.
|
||||
*/
|
||||
|
||||
struct fz_archive
|
||||
{
|
||||
int refs;
|
||||
|
||||
fz_stream *file;
|
||||
const char *format;
|
||||
|
||||
void (*drop_archive)(fz_context *ctx, fz_archive *arch);
|
||||
int (*count_entries)(fz_context *ctx, fz_archive *arch);
|
||||
const char *(*list_entry)(fz_context *ctx, fz_archive *arch, int idx);
|
||||
int (*has_entry)(fz_context *ctx, fz_archive *arch, const char *name);
|
||||
fz_buffer *(*read_entry)(fz_context *ctx, fz_archive *arch, const char *name);
|
||||
fz_stream *(*open_entry)(fz_context *ctx, fz_archive *arch, const char *name);
|
||||
};
|
||||
|
||||
fz_archive *fz_new_archive_of_size(fz_context *ctx, fz_stream *file, int size);
|
||||
|
||||
#define fz_new_derived_archive(C,F,M) \
|
||||
((M*)Memento_label(fz_new_archive_of_size(C, F, sizeof(M)), #M))
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,117 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_BAND_WRITER_H
|
||||
#define MUPDF_FITZ_BAND_WRITER_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/output.h"
|
||||
#include "mupdf/fitz/color.h"
|
||||
#include "mupdf/fitz/separation.h"
|
||||
|
||||
/**
|
||||
fz_band_writer
|
||||
*/
|
||||
typedef struct fz_band_writer fz_band_writer;
|
||||
|
||||
/**
|
||||
Cause a band writer to write the header for
|
||||
a banded image with the given properties/dimensions etc. This
|
||||
also configures the bandwriter for the format of the data to be
|
||||
passed in future calls.
|
||||
|
||||
w, h: Width and Height of the entire page.
|
||||
|
||||
n: Number of components (including spots and alphas).
|
||||
|
||||
alpha: Number of alpha components.
|
||||
|
||||
xres, yres: X and Y resolutions in dpi.
|
||||
|
||||
cs: Colorspace (NULL for bitmaps)
|
||||
|
||||
seps: Separation details (or NULL).
|
||||
*/
|
||||
void fz_write_header(fz_context *ctx, fz_band_writer *writer, int w, int h, int n, int alpha, int xres, int yres, int pagenum, fz_colorspace *cs, fz_separations *seps);
|
||||
|
||||
/**
|
||||
Cause a band writer to write the next band
|
||||
of data for an image.
|
||||
|
||||
stride: The byte offset from the first byte of the data
|
||||
for a pixel to the first byte of the data for the same pixel
|
||||
on the row below.
|
||||
|
||||
band_height: The number of lines in this band.
|
||||
|
||||
samples: Pointer to first byte of the data.
|
||||
*/
|
||||
void fz_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_height, const unsigned char *samples);
|
||||
|
||||
/**
|
||||
Finishes up the output and closes the band writer. After this
|
||||
call no more headers or bands may be written.
|
||||
*/
|
||||
void fz_close_band_writer(fz_context *ctx, fz_band_writer *writer);
|
||||
|
||||
/**
|
||||
Drop the reference to the band writer, causing it to be
|
||||
destroyed.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_drop_band_writer(fz_context *ctx, fz_band_writer *writer);
|
||||
|
||||
/* Implementation details: subject to change. */
|
||||
|
||||
typedef void (fz_write_header_fn)(fz_context *ctx, fz_band_writer *writer, fz_colorspace *cs);
|
||||
typedef void (fz_write_band_fn)(fz_context *ctx, fz_band_writer *writer, int stride, int band_start, int band_height, const unsigned char *samples);
|
||||
typedef void (fz_write_trailer_fn)(fz_context *ctx, fz_band_writer *writer);
|
||||
typedef void (fz_close_band_writer_fn)(fz_context *ctx, fz_band_writer *writer);
|
||||
typedef void (fz_drop_band_writer_fn)(fz_context *ctx, fz_band_writer *writer);
|
||||
|
||||
struct fz_band_writer
|
||||
{
|
||||
fz_drop_band_writer_fn *drop;
|
||||
fz_close_band_writer_fn *close;
|
||||
fz_write_header_fn *header;
|
||||
fz_write_band_fn *band;
|
||||
fz_write_trailer_fn *trailer;
|
||||
fz_output *out;
|
||||
int w;
|
||||
int h;
|
||||
int n;
|
||||
int s;
|
||||
int alpha;
|
||||
int xres;
|
||||
int yres;
|
||||
int pagenum;
|
||||
int line;
|
||||
fz_separations *seps;
|
||||
};
|
||||
|
||||
fz_band_writer *fz_new_band_writer_of_size(fz_context *ctx, size_t size, fz_output *out);
|
||||
#define fz_new_band_writer(C,M,O) ((M *)Memento_label(fz_new_band_writer_of_size(ctx, sizeof(M), O), #M))
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
Bidirectional text processing.
|
||||
|
||||
Derived from the SmartOffice code, which is itself derived
|
||||
from the example unicode standard code. Original copyright
|
||||
messages follow:
|
||||
|
||||
Copyright (C) Picsel, 2004-2008. All Rights Reserved.
|
||||
|
||||
Processes Unicode text by arranging the characters into an order
|
||||
suitable for display. E.g. Hebrew text will be arranged from
|
||||
right-to-left and any English within the text will remain in the
|
||||
left-to-right order.
|
||||
|
||||
This is an implementation of the Unicode Bidirectional Algorithm
|
||||
which can be found here: http://www.unicode.org/reports/tr9/ and
|
||||
is based on the reference implementation found on Unicode.org.
|
||||
*/
|
||||
|
||||
#ifndef FITZ_BIDI_H
|
||||
#define FITZ_BIDI_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
|
||||
/* Implementation details: subject to change. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FZ_BIDI_LTR = 0,
|
||||
FZ_BIDI_RTL = 1,
|
||||
FZ_BIDI_NEUTRAL = 2
|
||||
}
|
||||
fz_bidi_direction;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FZ_BIDI_CLASSIFY_WHITE_SPACE = 1,
|
||||
FZ_BIDI_REPLACE_TAB = 2
|
||||
}
|
||||
fz_bidi_flags;
|
||||
|
||||
/**
|
||||
Prototype for callback function supplied to fz_bidi_fragment_text.
|
||||
|
||||
@param fragment first character in fragment
|
||||
@param fragmentLen number of characters in fragment
|
||||
@param bidiLevel The bidirectional level for this text.
|
||||
The bottom bit will be set iff block
|
||||
should concatenate with other blocks as
|
||||
right-to-left
|
||||
@param script the script in use for this fragment (other
|
||||
than common or inherited)
|
||||
@param arg data from caller of Bidi_fragmentText
|
||||
*/
|
||||
typedef void (fz_bidi_fragment_fn)(const uint32_t *fragment,
|
||||
size_t fragmentLen,
|
||||
int bidiLevel,
|
||||
int script,
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
Partitions the given Unicode sequence into one or more
|
||||
unidirectional fragments and invokes the given callback
|
||||
function for each fragment.
|
||||
|
||||
For example, if directionality of text is:
|
||||
0123456789
|
||||
rrlllrrrrr,
|
||||
we'll invoke callback with:
|
||||
&text[0], length == 2
|
||||
&text[2], length == 3
|
||||
&text[5], length == 5
|
||||
|
||||
@param[in] text start of Unicode sequence
|
||||
@param[in] textlen number of Unicodes to analyse
|
||||
@param[in] baseDir direction of paragraph (specify FZ_BIDI_NEUTRAL to force auto-detection)
|
||||
@param[in] callback function to be called for each fragment
|
||||
@param[in] arg data to be passed to the callback function
|
||||
@param[in] flags flags to control operation (see fz_bidi_flags above)
|
||||
*/
|
||||
void fz_bidi_fragment_text(fz_context *ctx,
|
||||
const uint32_t *text,
|
||||
size_t textlen,
|
||||
fz_bidi_direction *baseDir,
|
||||
fz_bidi_fragment_fn *callback,
|
||||
void *arg,
|
||||
int flags);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,168 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_BITMAP_H
|
||||
#define MUPDF_FITZ_BITMAP_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/pixmap.h"
|
||||
|
||||
/**
|
||||
Bitmaps have 1 bit per component. Only used for creating
|
||||
halftoned versions of contone buffers, and saving out. Samples
|
||||
are stored msb first, akin to pbms.
|
||||
|
||||
The internals of this struct are considered implementation
|
||||
details and subject to change. Where possible, accessor
|
||||
functions should be used in preference.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int refs;
|
||||
int w, h, stride, n;
|
||||
int xres, yres;
|
||||
unsigned char *samples;
|
||||
} fz_bitmap;
|
||||
|
||||
/**
|
||||
Take an additional reference to the bitmap. The same pointer
|
||||
is returned.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit);
|
||||
|
||||
/**
|
||||
Drop a reference to the bitmap. When the reference count reaches
|
||||
zero, the bitmap will be destroyed.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit);
|
||||
|
||||
/**
|
||||
A halftone is a set of threshold tiles, one per component. Each
|
||||
threshold tile is a pixmap, possibly of varying sizes and
|
||||
phases. Currently, we only provide one 'default' halftone tile
|
||||
for operating on 1 component plus alpha pixmaps (where the alpha
|
||||
is ignored). This is signified by a fz_halftone pointer to NULL.
|
||||
*/
|
||||
typedef struct fz_halftone fz_halftone;
|
||||
|
||||
/**
|
||||
Make a bitmap from a pixmap and a halftone.
|
||||
|
||||
pix: The pixmap to generate from. Currently must be a single
|
||||
color component with no alpha.
|
||||
|
||||
ht: The halftone to use. NULL implies the default halftone.
|
||||
|
||||
Returns the resultant bitmap. Throws exceptions in the case of
|
||||
failure to allocate.
|
||||
*/
|
||||
fz_bitmap *fz_new_bitmap_from_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht);
|
||||
|
||||
/**
|
||||
Make a bitmap from a pixmap and a
|
||||
halftone, allowing for the position of the pixmap within an
|
||||
overall banded rendering.
|
||||
|
||||
pix: The pixmap to generate from. Currently must be a single
|
||||
color component with no alpha.
|
||||
|
||||
ht: The halftone to use. NULL implies the default halftone.
|
||||
|
||||
band_start: Vertical offset within the overall banded rendering
|
||||
(in pixels)
|
||||
|
||||
Returns the resultant bitmap. Throws exceptions in the case of
|
||||
failure to allocate.
|
||||
*/
|
||||
fz_bitmap *fz_new_bitmap_from_pixmap_band(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht, int band_start);
|
||||
|
||||
/**
|
||||
Create a new bitmap.
|
||||
|
||||
w, h: Width and Height for the bitmap
|
||||
|
||||
n: Number of color components (assumed to be a divisor of 8)
|
||||
|
||||
xres, yres: X and Y resolutions (in pixels per inch).
|
||||
|
||||
Returns pointer to created bitmap structure. The bitmap
|
||||
data is uninitialised.
|
||||
*/
|
||||
fz_bitmap *fz_new_bitmap(fz_context *ctx, int w, int h, int n, int xres, int yres);
|
||||
|
||||
/**
|
||||
Retrieve details of a given bitmap.
|
||||
|
||||
bitmap: The bitmap to query.
|
||||
|
||||
w: Pointer to storage to retrieve width (or NULL).
|
||||
|
||||
h: Pointer to storage to retrieve height (or NULL).
|
||||
|
||||
n: Pointer to storage to retrieve number of color components (or
|
||||
NULL).
|
||||
|
||||
stride: Pointer to storage to retrieve bitmap stride (or NULL).
|
||||
*/
|
||||
void fz_bitmap_details(fz_bitmap *bitmap, int *w, int *h, int *n, int *stride);
|
||||
|
||||
/**
|
||||
Set the entire bitmap to 0.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit);
|
||||
|
||||
/**
|
||||
Create a 'default' halftone structure
|
||||
for the given number of components.
|
||||
|
||||
num_comps: The number of components to use.
|
||||
|
||||
Returns a simple default halftone. The default halftone uses
|
||||
the same halftone tile for each plane, which may not be ideal
|
||||
for all purposes.
|
||||
*/
|
||||
fz_halftone *fz_default_halftone(fz_context *ctx, int num_comps);
|
||||
|
||||
/**
|
||||
Take an additional reference to the halftone. The same pointer
|
||||
is returned.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half);
|
||||
|
||||
/**
|
||||
Drop a reference to the halftone. When the reference count
|
||||
reaches zero, the halftone is destroyed.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_drop_halftone(fz_context *ctx, fz_halftone *ht);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,250 @@
|
||||
// Copyright (C) 2004-2023 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_BUFFER_H
|
||||
#define MUPDF_FITZ_BUFFER_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
|
||||
/**
|
||||
fz_buffer is a wrapper around a dynamically allocated array of
|
||||
bytes.
|
||||
|
||||
Buffers have a capacity (the number of bytes storage immediately
|
||||
available) and a current size.
|
||||
|
||||
The contents of the structure are considered implementation
|
||||
details and are subject to change. Users should use the accessor
|
||||
functions in preference.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int refs;
|
||||
unsigned char *data;
|
||||
size_t cap, len;
|
||||
int unused_bits;
|
||||
int shared;
|
||||
} fz_buffer;
|
||||
|
||||
/**
|
||||
Take an additional reference to the buffer. The same pointer
|
||||
is returned.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Drop a reference to the buffer. When the reference count reaches
|
||||
zero, the buffer is destroyed.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_drop_buffer(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Retrieve internal memory of buffer.
|
||||
|
||||
datap: Output parameter that will be pointed to the data.
|
||||
|
||||
Returns the current size of the data in bytes.
|
||||
*/
|
||||
size_t fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap);
|
||||
|
||||
/**
|
||||
Ensure that a buffer's data ends in a
|
||||
0 byte, and return a pointer to it.
|
||||
*/
|
||||
const char *fz_string_from_buffer(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
fz_buffer *fz_new_buffer(fz_context *ctx, size_t capacity);
|
||||
|
||||
/**
|
||||
Create a new buffer with existing data.
|
||||
|
||||
data: Pointer to existing data.
|
||||
size: Size of existing data.
|
||||
|
||||
Takes ownership of data. Does not make a copy. Calls fz_free on
|
||||
the data when the buffer is deallocated. Do not use 'data' after
|
||||
passing to this function.
|
||||
|
||||
Returns pointer to new buffer. Throws exception on allocation
|
||||
failure.
|
||||
*/
|
||||
fz_buffer *fz_new_buffer_from_data(fz_context *ctx, unsigned char *data, size_t size);
|
||||
|
||||
/**
|
||||
Like fz_new_buffer, but does not take ownership.
|
||||
*/
|
||||
fz_buffer *fz_new_buffer_from_shared_data(fz_context *ctx, const unsigned char *data, size_t size);
|
||||
|
||||
/**
|
||||
Create a new buffer containing a copy of the passed data.
|
||||
*/
|
||||
fz_buffer *fz_new_buffer_from_copied_data(fz_context *ctx, const unsigned char *data, size_t size);
|
||||
|
||||
/**
|
||||
Make a new buffer, containing a copy of the data used in
|
||||
the original.
|
||||
*/
|
||||
fz_buffer *fz_clone_buffer(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Create a new buffer with data decoded from a base64 input string.
|
||||
*/
|
||||
fz_buffer *fz_new_buffer_from_base64(fz_context *ctx, const char *data, size_t size);
|
||||
|
||||
/**
|
||||
Ensure that a buffer has a given capacity,
|
||||
truncating data if required.
|
||||
|
||||
capacity: The desired capacity for the buffer. If the current
|
||||
size of the buffer contents is smaller than capacity, it is
|
||||
truncated.
|
||||
*/
|
||||
void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, size_t capacity);
|
||||
|
||||
/**
|
||||
Make some space within a buffer (i.e. ensure that
|
||||
capacity > size).
|
||||
*/
|
||||
void fz_grow_buffer(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Trim wasted capacity from a buffer by resizing internal memory.
|
||||
*/
|
||||
void fz_trim_buffer(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Empties the buffer. Storage is not freed, but is held ready
|
||||
to be reused as the buffer is refilled.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_clear_buffer(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Create a new buffer with a (subset of) the data from the buffer.
|
||||
|
||||
start: if >= 0, offset from start of buffer, if < 0 offset from end of buffer.
|
||||
|
||||
end: if >= 0, offset from start of buffer, if < 0 offset from end of buffer.
|
||||
|
||||
*/
|
||||
fz_buffer *fz_slice_buffer(fz_context *ctx, fz_buffer *buf, int64_t start, int64_t end);
|
||||
|
||||
/**
|
||||
Append the contents of the source buffer onto the end of the
|
||||
destination buffer, extending automatically as required.
|
||||
|
||||
Ownership of buffers does not change.
|
||||
*/
|
||||
void fz_append_buffer(fz_context *ctx, fz_buffer *destination, fz_buffer *source);
|
||||
|
||||
/**
|
||||
Write a base64 encoded data block, optionally with periodic newlines.
|
||||
*/
|
||||
void fz_append_base64(fz_context *ctx, fz_buffer *out, const unsigned char *data, size_t size, int newline);
|
||||
|
||||
/**
|
||||
Append a base64 encoded fz_buffer, optionally with periodic newlines.
|
||||
*/
|
||||
void fz_append_base64_buffer(fz_context *ctx, fz_buffer *out, fz_buffer *data, int newline);
|
||||
|
||||
/**
|
||||
fz_append_*: Append data to a buffer.
|
||||
|
||||
The buffer will automatically grow as required.
|
||||
*/
|
||||
void fz_append_data(fz_context *ctx, fz_buffer *buf, const void *data, size_t len);
|
||||
void fz_append_string(fz_context *ctx, fz_buffer *buf, const char *data);
|
||||
void fz_append_byte(fz_context *ctx, fz_buffer *buf, int c);
|
||||
void fz_append_rune(fz_context *ctx, fz_buffer *buf, int c);
|
||||
void fz_append_int32_le(fz_context *ctx, fz_buffer *buf, int x);
|
||||
void fz_append_int16_le(fz_context *ctx, fz_buffer *buf, int x);
|
||||
void fz_append_int32_be(fz_context *ctx, fz_buffer *buf, int x);
|
||||
void fz_append_int16_be(fz_context *ctx, fz_buffer *buf, int x);
|
||||
void fz_append_bits(fz_context *ctx, fz_buffer *buf, int value, int count);
|
||||
void fz_append_bits_pad(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
fz_append_pdf_string: Append a string with PDF syntax quotes and
|
||||
escapes.
|
||||
|
||||
The buffer will automatically grow as required.
|
||||
*/
|
||||
void fz_append_pdf_string(fz_context *ctx, fz_buffer *buffer, const char *text);
|
||||
|
||||
/**
|
||||
fz_append_printf: Format and append data to buffer using
|
||||
printf-like formatting (see fz_vsnprintf).
|
||||
|
||||
The buffer will automatically grow as required.
|
||||
*/
|
||||
void fz_append_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...);
|
||||
|
||||
/**
|
||||
fz_append_vprintf: Format and append data to buffer using
|
||||
printf-like formatting with varargs (see fz_vsnprintf).
|
||||
*/
|
||||
void fz_append_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args);
|
||||
|
||||
/**
|
||||
Zero-terminate buffer in order to use as a C string.
|
||||
|
||||
This byte is invisible and does not affect the length of the
|
||||
buffer as returned by fz_buffer_storage. The zero byte is
|
||||
written *after* the data, and subsequent writes will overwrite
|
||||
the terminating byte.
|
||||
|
||||
Subsequent changes to the size of the buffer (such as by
|
||||
fz_buffer_trim, fz_buffer_grow, fz_resize_buffer, etc) may
|
||||
invalidate this.
|
||||
*/
|
||||
void fz_terminate_buffer(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Create an MD5 digest from buffer contents.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_md5_buffer(fz_context *ctx, fz_buffer *buffer, unsigned char digest[16]);
|
||||
|
||||
/**
|
||||
Take ownership of buffer contents.
|
||||
|
||||
Performs the same task as fz_buffer_storage, but ownership of
|
||||
the data buffer returns with this call. The buffer is left
|
||||
empty.
|
||||
|
||||
Note: Bad things may happen if this is called on a buffer with
|
||||
multiple references that is being used from multiple threads.
|
||||
|
||||
data: Pointer to place to retrieve data pointer.
|
||||
|
||||
Returns length of stream.
|
||||
*/
|
||||
size_t fz_buffer_extract(fz_context *ctx, fz_buffer *buf, unsigned char **data);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,427 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_COLOR_H
|
||||
#define MUPDF_FITZ_COLOR_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/store.h"
|
||||
|
||||
#if FZ_ENABLE_ICC
|
||||
/**
|
||||
Opaque type for an ICC Profile.
|
||||
*/
|
||||
typedef struct fz_icc_profile fz_icc_profile;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Describes a given colorspace.
|
||||
*/
|
||||
typedef struct fz_colorspace fz_colorspace;
|
||||
|
||||
/**
|
||||
Pixmaps represent a set of pixels for a 2 dimensional region of
|
||||
a plane. Each pixel has n components per pixel. The components
|
||||
are in the order process-components, spot-colors, alpha, where
|
||||
there can be 0 of any of those types. The data is in
|
||||
premultiplied alpha when rendering, but non-premultiplied for
|
||||
colorspace conversions and rescaling.
|
||||
*/
|
||||
typedef struct fz_pixmap fz_pixmap;
|
||||
|
||||
/* Color handling parameters: rendering intent, overprint, etc. */
|
||||
|
||||
enum
|
||||
{
|
||||
/* Same order as needed by lcms */
|
||||
FZ_RI_PERCEPTUAL,
|
||||
FZ_RI_RELATIVE_COLORIMETRIC,
|
||||
FZ_RI_SATURATION,
|
||||
FZ_RI_ABSOLUTE_COLORIMETRIC,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ri; /* rendering intent */
|
||||
uint8_t bp; /* black point compensation */
|
||||
uint8_t op; /* overprinting */
|
||||
uint8_t opm; /* overprint mode */
|
||||
} fz_color_params;
|
||||
|
||||
FZ_DATA extern const fz_color_params fz_default_color_params;
|
||||
|
||||
/**
|
||||
Map from (case sensitive) rendering intent string to enumeration
|
||||
value.
|
||||
*/
|
||||
int fz_lookup_rendering_intent(const char *name);
|
||||
|
||||
/**
|
||||
Map from enumerated rendering intent to string.
|
||||
|
||||
The returned string is static and therefore must not be freed.
|
||||
*/
|
||||
const char *fz_rendering_intent_name(int ri);
|
||||
|
||||
/**
|
||||
The maximum number of colorants available in any given
|
||||
color/colorspace (not including alpha).
|
||||
|
||||
Changing this value will alter the amount of memory being used
|
||||
(both stack and heap space), but not hugely. Speed should
|
||||
(largely) be determined by the number of colors actually used.
|
||||
*/
|
||||
enum { FZ_MAX_COLORS = 32 };
|
||||
|
||||
enum fz_colorspace_type
|
||||
{
|
||||
FZ_COLORSPACE_NONE,
|
||||
FZ_COLORSPACE_GRAY,
|
||||
FZ_COLORSPACE_RGB,
|
||||
FZ_COLORSPACE_BGR,
|
||||
FZ_COLORSPACE_CMYK,
|
||||
FZ_COLORSPACE_LAB,
|
||||
FZ_COLORSPACE_INDEXED,
|
||||
FZ_COLORSPACE_SEPARATION,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FZ_COLORSPACE_IS_DEVICE = 1,
|
||||
FZ_COLORSPACE_IS_ICC = 2,
|
||||
FZ_COLORSPACE_HAS_CMYK = 4,
|
||||
FZ_COLORSPACE_HAS_SPOTS = 8,
|
||||
FZ_COLORSPACE_HAS_CMYK_AND_SPOTS = 4|8,
|
||||
};
|
||||
|
||||
/**
|
||||
Creates a new colorspace instance and returns a reference.
|
||||
|
||||
No internal checking is done that the colorspace type (e.g.
|
||||
CMYK) matches with the flags (e.g. FZ_COLORSPACE_HAS_CMYK) or
|
||||
colorant count (n) or name.
|
||||
|
||||
The reference should be dropped when it is finished with.
|
||||
|
||||
Colorspaces are immutable once created (with the exception of
|
||||
setting up colorant names for separation spaces).
|
||||
*/
|
||||
fz_colorspace *fz_new_colorspace(fz_context *ctx, enum fz_colorspace_type type, int flags, int n, const char *name);
|
||||
|
||||
/**
|
||||
Increment the reference count for the colorspace.
|
||||
|
||||
Returns the same pointer. Never throws an exception.
|
||||
*/
|
||||
fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace);
|
||||
|
||||
/**
|
||||
Drops a reference to the colorspace.
|
||||
|
||||
When the reference count reaches zero, the colorspace is
|
||||
destroyed.
|
||||
*/
|
||||
void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace);
|
||||
|
||||
/**
|
||||
Create an indexed colorspace.
|
||||
|
||||
The supplied lookup table is high palette entries long. Each
|
||||
entry is n bytes long, where n is given by the number of
|
||||
colorants in the base colorspace, one byte per colorant.
|
||||
|
||||
Ownership of lookup is passed it; it will be freed on
|
||||
destruction, so must be heap allocated.
|
||||
|
||||
The colorspace will keep an additional reference to the base
|
||||
colorspace that will be dropped on destruction.
|
||||
|
||||
The returned reference should be dropped when it is finished
|
||||
with.
|
||||
|
||||
Colorspaces are immutable once created.
|
||||
*/
|
||||
fz_colorspace *fz_new_indexed_colorspace(fz_context *ctx, fz_colorspace *base, int high, unsigned char *lookup);
|
||||
|
||||
/**
|
||||
Create a colorspace from an ICC profile supplied in buf.
|
||||
|
||||
Limited checking is done to ensure that the colorspace type is
|
||||
appropriate for the supplied ICC profile.
|
||||
|
||||
An additional reference is taken to buf, which will be dropped
|
||||
on destruction. Ownership is NOT passed in.
|
||||
|
||||
The returned reference should be dropped when it is finished
|
||||
with.
|
||||
|
||||
Colorspaces are immutable once created.
|
||||
*/
|
||||
fz_colorspace *fz_new_icc_colorspace(fz_context *ctx, enum fz_colorspace_type type, int flags, const char *name, fz_buffer *buf);
|
||||
|
||||
|
||||
/**
|
||||
Create a calibrated gray colorspace.
|
||||
|
||||
The returned reference should be dropped when it is finished
|
||||
with.
|
||||
|
||||
Colorspaces are immutable once created.
|
||||
*/
|
||||
fz_colorspace *fz_new_cal_gray_colorspace(fz_context *ctx, float wp[3], float bp[3], float gamma);
|
||||
|
||||
/**
|
||||
Create a calibrated rgb colorspace.
|
||||
|
||||
The returned reference should be dropped when it is finished
|
||||
with.
|
||||
|
||||
Colorspaces are immutable once created.
|
||||
*/
|
||||
fz_colorspace *fz_new_cal_rgb_colorspace(fz_context *ctx, float wp[3], float bp[3], float gamma[3], float matrix[9]);
|
||||
|
||||
/**
|
||||
Query the type of colorspace.
|
||||
*/
|
||||
enum fz_colorspace_type fz_colorspace_type(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
Query the name of a colorspace.
|
||||
|
||||
The returned string has the same lifespan as the colorspace
|
||||
does. Caller should not free it.
|
||||
*/
|
||||
const char *fz_colorspace_name(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
Query the number of colorants in a colorspace.
|
||||
*/
|
||||
int fz_colorspace_n(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
True for CMYK, Separation and DeviceN colorspaces.
|
||||
*/
|
||||
int fz_colorspace_is_subtractive(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
True if DeviceN color space has only colorants from the CMYK set.
|
||||
*/
|
||||
int fz_colorspace_device_n_has_only_cmyk(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
True if DeviceN color space has cyan magenta yellow or black as
|
||||
one of its colorants.
|
||||
*/
|
||||
int fz_colorspace_device_n_has_cmyk(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
Tests for particular types of colorspaces
|
||||
*/
|
||||
int fz_colorspace_is_gray(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_rgb(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_cmyk(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_lab(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_indexed(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_device_n(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_device(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_device_gray(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_device_cmyk(fz_context *ctx, fz_colorspace *cs);
|
||||
int fz_colorspace_is_lab_icc(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
Check to see that a colorspace is appropriate to be used as
|
||||
a blending space (i.e. only grey, rgb or cmyk).
|
||||
*/
|
||||
int fz_is_valid_blend_colorspace(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
Get the 'base' colorspace for a colorspace.
|
||||
|
||||
For indexed colorspaces, this is the colorspace the index
|
||||
decodes into. For all other colorspaces, it is the colorspace
|
||||
itself.
|
||||
|
||||
The returned colorspace is 'borrowed' (i.e. no additional
|
||||
references are taken or dropped).
|
||||
*/
|
||||
fz_colorspace *fz_base_colorspace(fz_context *ctx, fz_colorspace *cs);
|
||||
|
||||
/**
|
||||
Retrieve global default colorspaces.
|
||||
|
||||
These return borrowed references that should not be dropped,
|
||||
unless they are kept first.
|
||||
*/
|
||||
fz_colorspace *fz_device_gray(fz_context *ctx);
|
||||
fz_colorspace *fz_device_rgb(fz_context *ctx);
|
||||
fz_colorspace *fz_device_bgr(fz_context *ctx);
|
||||
fz_colorspace *fz_device_cmyk(fz_context *ctx);
|
||||
fz_colorspace *fz_device_lab(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Assign a name for a given colorant in a colorspace.
|
||||
|
||||
Used while initially setting up a colorspace. The string is
|
||||
copied into local storage, so need not be retained by the
|
||||
caller.
|
||||
*/
|
||||
void fz_colorspace_name_colorant(fz_context *ctx, fz_colorspace *cs, int n, const char *name);
|
||||
|
||||
/**
|
||||
Retrieve a the name for a colorant.
|
||||
|
||||
Returns a pointer with the same lifespan as the colorspace.
|
||||
*/
|
||||
const char *fz_colorspace_colorant(fz_context *ctx, fz_colorspace *cs, int n);
|
||||
|
||||
/* Color conversion */
|
||||
|
||||
/**
|
||||
Clamp the samples in a color to the correct ranges for a
|
||||
given colorspace.
|
||||
*/
|
||||
void fz_clamp_color(fz_context *ctx, fz_colorspace *cs, const float *in, float *out);
|
||||
|
||||
/**
|
||||
Convert color values sv from colorspace ss into colorvalues dv
|
||||
for colorspace ds, via an optional intervening space is,
|
||||
respecting the given color_params.
|
||||
*/
|
||||
void fz_convert_color(fz_context *ctx, fz_colorspace *ss, const float *sv, fz_colorspace *ds, float *dv, fz_colorspace *is, fz_color_params params);
|
||||
|
||||
/* Default (fallback) colorspace handling */
|
||||
|
||||
/**
|
||||
Structure to hold default colorspaces.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int refs;
|
||||
fz_colorspace *gray;
|
||||
fz_colorspace *rgb;
|
||||
fz_colorspace *cmyk;
|
||||
fz_colorspace *oi;
|
||||
} fz_default_colorspaces;
|
||||
|
||||
/**
|
||||
Create a new default colorspace structure with values inherited
|
||||
from the context, and return a reference to it.
|
||||
|
||||
These can be overridden using fz_set_default_xxxx.
|
||||
|
||||
These should not be overridden while more than one caller has
|
||||
the reference for fear of race conditions.
|
||||
|
||||
The caller should drop this reference once finished with it.
|
||||
*/
|
||||
fz_default_colorspaces *fz_new_default_colorspaces(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Keep an additional reference to the default colorspaces
|
||||
structure.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
fz_default_colorspaces* fz_keep_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs);
|
||||
|
||||
/**
|
||||
Drop a reference to the default colorspaces structure. When the
|
||||
reference count reaches 0, the references it holds internally
|
||||
to the underlying colorspaces will be dropped, and the structure
|
||||
will be destroyed.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_drop_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs);
|
||||
|
||||
/**
|
||||
Returns a reference to a newly cloned default colorspaces
|
||||
structure.
|
||||
|
||||
The new clone may safely be altered without fear of race
|
||||
conditions as the caller is the only reference holder.
|
||||
*/
|
||||
fz_default_colorspaces *fz_clone_default_colorspaces(fz_context *ctx, fz_default_colorspaces *base);
|
||||
|
||||
/**
|
||||
Retrieve default colorspaces (typically page local).
|
||||
|
||||
If default_cs is non NULL, the default is retrieved from there,
|
||||
otherwise the global default is retrieved.
|
||||
|
||||
These return borrowed references that should not be dropped,
|
||||
unless they are kept first.
|
||||
*/
|
||||
fz_colorspace *fz_default_gray(fz_context *ctx, const fz_default_colorspaces *default_cs);
|
||||
fz_colorspace *fz_default_rgb(fz_context *ctx, const fz_default_colorspaces *default_cs);
|
||||
fz_colorspace *fz_default_cmyk(fz_context *ctx, const fz_default_colorspaces *default_cs);
|
||||
fz_colorspace *fz_default_output_intent(fz_context *ctx, const fz_default_colorspaces *default_cs);
|
||||
|
||||
/**
|
||||
Set new defaults within the default colorspace structure.
|
||||
|
||||
New references are taken to the new default, and references to
|
||||
the old defaults dropped.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_set_default_gray(fz_context *ctx, fz_default_colorspaces *default_cs, fz_colorspace *cs);
|
||||
void fz_set_default_rgb(fz_context *ctx, fz_default_colorspaces *default_cs, fz_colorspace *cs);
|
||||
void fz_set_default_cmyk(fz_context *ctx, fz_default_colorspaces *default_cs, fz_colorspace *cs);
|
||||
void fz_set_default_output_intent(fz_context *ctx, fz_default_colorspaces *default_cs, fz_colorspace *cs);
|
||||
|
||||
/* Implementation details: subject to change. */
|
||||
|
||||
struct fz_colorspace
|
||||
{
|
||||
fz_key_storable key_storable;
|
||||
enum fz_colorspace_type type;
|
||||
int flags;
|
||||
int n;
|
||||
char *name;
|
||||
union {
|
||||
#if FZ_ENABLE_ICC
|
||||
struct {
|
||||
fz_buffer *buffer;
|
||||
unsigned char md5[16];
|
||||
fz_icc_profile *profile;
|
||||
} icc;
|
||||
#endif
|
||||
struct {
|
||||
fz_colorspace *base;
|
||||
int high;
|
||||
unsigned char *lookup;
|
||||
} indexed;
|
||||
struct {
|
||||
fz_colorspace *base;
|
||||
void (*eval)(fz_context *ctx, void *tint, const float *s, int sn, float *d, int dn);
|
||||
void (*drop)(fz_context *ctx, void *tint);
|
||||
void *tint;
|
||||
char *colorant[FZ_MAX_COLORS];
|
||||
} separation;
|
||||
} u;
|
||||
};
|
||||
|
||||
void fz_drop_colorspace_imp(fz_context *ctx, fz_storable *cs_);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_COMPRESS_H
|
||||
#define MUPDF_FITZ_COMPRESS_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/buffer.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FZ_DEFLATE_NONE = 0,
|
||||
FZ_DEFLATE_BEST_SPEED = 1,
|
||||
FZ_DEFLATE_BEST = 9,
|
||||
FZ_DEFLATE_DEFAULT = -1
|
||||
} fz_deflate_level;
|
||||
|
||||
/**
|
||||
Returns the upper bound on the
|
||||
size of flated data of length size.
|
||||
*/
|
||||
size_t fz_deflate_bound(fz_context *ctx, size_t size);
|
||||
|
||||
/**
|
||||
Compress source_length bytes of data starting
|
||||
at source, into a buffer of length *destLen, starting at dest.
|
||||
*compressed_length will be updated on exit to contain the size
|
||||
actually used.
|
||||
*/
|
||||
void fz_deflate(fz_context *ctx, unsigned char *dest, size_t *compressed_length, const unsigned char *source, size_t source_length, fz_deflate_level level);
|
||||
|
||||
/**
|
||||
Compress source_length bytes of data starting
|
||||
at source, into a new memory block malloced for that purpose.
|
||||
*compressed_length is updated on exit to contain the size used.
|
||||
Ownership of the block is returned from this function, and the
|
||||
caller is therefore responsible for freeing it. The block may be
|
||||
considerably larger than is actually required. The caller is
|
||||
free to fz_realloc it down if it wants to.
|
||||
*/
|
||||
unsigned char *fz_new_deflated_data(fz_context *ctx, size_t *compressed_length, const unsigned char *source, size_t source_length, fz_deflate_level level);
|
||||
|
||||
/**
|
||||
Compress the contents of a fz_buffer into a
|
||||
new block malloced for that purpose. *compressed_length is
|
||||
updated on exit to contain the size used. Ownership of the block
|
||||
is returned from this function, and the caller is therefore
|
||||
responsible for freeing it. The block may be considerably larger
|
||||
than is actually required. The caller is free to fz_realloc it
|
||||
down if it wants to.
|
||||
*/
|
||||
unsigned char *fz_new_deflated_data_from_buffer(fz_context *ctx, size_t *compressed_length, fz_buffer *buffer, fz_deflate_level level);
|
||||
|
||||
/**
|
||||
Compress bitmap data as CCITT Group 3 1D fax image.
|
||||
Creates a stream assuming the default PDF parameters,
|
||||
except the number of columns.
|
||||
*/
|
||||
fz_buffer *fz_compress_ccitt_fax_g3(fz_context *ctx, const unsigned char *data, int columns, int rows);
|
||||
|
||||
/**
|
||||
Compress bitmap data as CCITT Group 4 2D fax image.
|
||||
Creates a stream assuming the default PDF parameters, except
|
||||
K=-1 and the number of columns.
|
||||
*/
|
||||
fz_buffer *fz_compress_ccitt_fax_g4(fz_context *ctx, const unsigned char *data, int columns, int rows);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,173 @@
|
||||
// Copyright (C) 2004-2023 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_COMPRESSED_BUFFER_H
|
||||
#define MUPDF_FITZ_COMPRESSED_BUFFER_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/buffer.h"
|
||||
#include "mupdf/fitz/stream.h"
|
||||
#include "mupdf/fitz/filter.h"
|
||||
|
||||
/**
|
||||
Compression parameters used for buffers of compressed data;
|
||||
typically for the source data for images.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
union {
|
||||
struct {
|
||||
int color_transform; /* Use -1 for unset */
|
||||
} jpeg;
|
||||
struct {
|
||||
int smask_in_data;
|
||||
} jpx;
|
||||
struct {
|
||||
fz_jbig2_globals *globals;
|
||||
int embedded;
|
||||
} jbig2;
|
||||
struct {
|
||||
int columns;
|
||||
int rows;
|
||||
int k;
|
||||
int end_of_line;
|
||||
int encoded_byte_align;
|
||||
int end_of_block;
|
||||
int black_is_1;
|
||||
int damaged_rows_before_error;
|
||||
} fax;
|
||||
struct
|
||||
{
|
||||
int columns;
|
||||
int colors;
|
||||
int predictor;
|
||||
int bpc;
|
||||
}
|
||||
flate;
|
||||
struct
|
||||
{
|
||||
int columns;
|
||||
int colors;
|
||||
int predictor;
|
||||
int bpc;
|
||||
int early_change;
|
||||
} lzw;
|
||||
} u;
|
||||
} fz_compression_params;
|
||||
|
||||
/**
|
||||
Buffers of compressed data; typically for the source data
|
||||
for images.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
fz_compression_params params;
|
||||
fz_buffer *buffer;
|
||||
} fz_compressed_buffer;
|
||||
|
||||
/**
|
||||
Return the storage size used for a buffer and its data.
|
||||
Used in implementing store handling.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
size_t fz_compressed_buffer_size(fz_compressed_buffer *buffer);
|
||||
|
||||
/**
|
||||
Open a stream to read the decompressed version of a buffer.
|
||||
*/
|
||||
fz_stream *fz_open_compressed_buffer(fz_context *ctx, fz_compressed_buffer *);
|
||||
|
||||
/**
|
||||
Open a stream to read the decompressed version of a buffer,
|
||||
with optional log2 subsampling.
|
||||
|
||||
l2factor = NULL for no subsampling, or a pointer to an integer
|
||||
containing the maximum log2 subsample factor acceptable (0 =
|
||||
none, 1 = halve dimensions, 2 = quarter dimensions etc). If
|
||||
non-NULL, then *l2factor will be updated on exit with the actual
|
||||
log2 subsample factor achieved.
|
||||
*/
|
||||
fz_stream *fz_open_image_decomp_stream_from_buffer(fz_context *ctx, fz_compressed_buffer *, int *l2factor);
|
||||
|
||||
/**
|
||||
Open a stream to read the decompressed version of another stream
|
||||
with optional log2 subsampling.
|
||||
*/
|
||||
fz_stream *fz_open_image_decomp_stream(fz_context *ctx, fz_stream *, fz_compression_params *, int *l2factor);
|
||||
|
||||
/**
|
||||
Recognise image format strings in the first 8 bytes from image
|
||||
data.
|
||||
*/
|
||||
int fz_recognize_image_format(fz_context *ctx, unsigned char p[8]);
|
||||
|
||||
/**
|
||||
Map from FZ_IMAGE_* value to string.
|
||||
|
||||
The returned string is static and therefore must not be freed.
|
||||
*/
|
||||
const char *fz_image_type_name(int type);
|
||||
|
||||
/**
|
||||
Map from (case sensitive) image type string to FZ_IMAGE_*
|
||||
type value.
|
||||
*/
|
||||
int fz_lookup_image_type(const char *type);
|
||||
|
||||
enum
|
||||
{
|
||||
FZ_IMAGE_UNKNOWN = 0,
|
||||
|
||||
/* Uncompressed samples */
|
||||
FZ_IMAGE_RAW,
|
||||
|
||||
/* Compressed samples */
|
||||
FZ_IMAGE_FAX,
|
||||
FZ_IMAGE_FLATE,
|
||||
FZ_IMAGE_LZW,
|
||||
FZ_IMAGE_RLD,
|
||||
|
||||
/* Full image formats */
|
||||
FZ_IMAGE_BMP,
|
||||
FZ_IMAGE_GIF,
|
||||
FZ_IMAGE_JBIG2,
|
||||
FZ_IMAGE_JPEG,
|
||||
FZ_IMAGE_JPX,
|
||||
FZ_IMAGE_JXR,
|
||||
FZ_IMAGE_PNG,
|
||||
FZ_IMAGE_PNM,
|
||||
FZ_IMAGE_TIFF,
|
||||
FZ_IMAGE_PSD,
|
||||
};
|
||||
|
||||
/**
|
||||
Drop a reference to a compressed buffer. Destroys the buffer
|
||||
and frees any storage/other references held by it.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_drop_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buf);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,222 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef FZ_CONFIG_H
|
||||
|
||||
#define FZ_CONFIG_H
|
||||
|
||||
/**
|
||||
Enable the following for spot (and hence overprint/overprint
|
||||
simulation) capable rendering. This forces FZ_PLOTTERS_N on.
|
||||
*/
|
||||
/* #define FZ_ENABLE_SPOT_RENDERING 1 */
|
||||
|
||||
/**
|
||||
Choose which plotters we need.
|
||||
By default we build all the plotters in. To avoid building
|
||||
plotters in that aren't needed, define the unwanted
|
||||
FZ_PLOTTERS_... define to 0.
|
||||
*/
|
||||
/* #define FZ_PLOTTERS_G 1 */
|
||||
/* #define FZ_PLOTTERS_RGB 1 */
|
||||
/* #define FZ_PLOTTERS_CMYK 1 */
|
||||
/* #define FZ_PLOTTERS_N 1 */
|
||||
|
||||
/**
|
||||
Choose which document agents to include.
|
||||
By default all are enabled. To avoid building unwanted
|
||||
ones, define FZ_ENABLE_... to 0.
|
||||
*/
|
||||
/* #define FZ_ENABLE_PDF 1 */
|
||||
/* #define FZ_ENABLE_XPS 1 */
|
||||
/* #define FZ_ENABLE_SVG 1 */
|
||||
/* #define FZ_ENABLE_CBZ 1 */
|
||||
/* #define FZ_ENABLE_IMG 1 */
|
||||
/* #define FZ_ENABLE_HTML 1 */
|
||||
/* #define FZ_ENABLE_EPUB 1 */
|
||||
|
||||
/**
|
||||
Choose which document writers to include.
|
||||
By default all are enabled. To avoid building unwanted
|
||||
ones, define FZ_ENABLE_..._OUTPUT to 0.
|
||||
*/
|
||||
/* #define FZ_ENABLE_OCR_OUTPUT 1 */
|
||||
/* #define FZ_ENABLE_DOCX_OUTPUT 1 */
|
||||
/* #define FZ_ENABLE_ODT_OUTPUT 1 */
|
||||
|
||||
/**
|
||||
Choose whether to enable ICC color profiles.
|
||||
*/
|
||||
/* #define FZ_ENABLE_ICC 1 */
|
||||
|
||||
/**
|
||||
Choose whether to enable JPEG2000 decoding.
|
||||
By default, it is enabled, but due to frequent security
|
||||
issues with the third party libraries we support disabling
|
||||
it with this flag.
|
||||
*/
|
||||
/* #define FZ_ENABLE_JPX 1 */
|
||||
|
||||
/**
|
||||
Choose whether to enable JavaScript.
|
||||
By default JavaScript is enabled both for mutool and PDF
|
||||
interactivity.
|
||||
*/
|
||||
/* #define FZ_ENABLE_JS 1 */
|
||||
|
||||
/**
|
||||
Choose which fonts to include.
|
||||
By default we include the base 14 PDF fonts,
|
||||
DroidSansFallback from Android for CJK, and
|
||||
Charis SIL from SIL for epub/html.
|
||||
Enable the following defines to AVOID including
|
||||
unwanted fonts.
|
||||
*/
|
||||
/* To avoid all noto fonts except CJK, enable: */
|
||||
#define TOFU 1
|
||||
|
||||
/* To skip the CJK font, enable: (this implicitly enables TOFU_CJK_EXT
|
||||
* and TOFU_CJK_LANG) */
|
||||
#define TOFU_CJK 1
|
||||
|
||||
/* To skip CJK Extension A, enable: (this implicitly enables
|
||||
* TOFU_CJK_LANG) */
|
||||
/* #define TOFU_CJK_EXT */
|
||||
|
||||
/* To skip CJK language specific fonts, enable: */
|
||||
/* #define TOFU_CJK_LANG */
|
||||
|
||||
/* To skip the Emoji font, enable: */
|
||||
/* #define TOFU_EMOJI */
|
||||
|
||||
/* To skip the ancient/historic scripts, enable: */
|
||||
/* #define TOFU_HISTORIC */
|
||||
|
||||
/* To skip the symbol font, enable: */
|
||||
/* #define TOFU_SYMBOL */
|
||||
|
||||
/* To skip the SIL fonts, enable: */
|
||||
/* #define TOFU_SIL */
|
||||
|
||||
/* To skip the Base14 fonts, enable: */
|
||||
/* #define TOFU_BASE14 */
|
||||
/* (You probably really don't want to do that except for measurement
|
||||
* purposes!) */
|
||||
|
||||
/* ---------- DO NOT EDIT ANYTHING UNDER THIS LINE ---------- */
|
||||
|
||||
#ifndef FZ_ENABLE_SPOT_RENDERING
|
||||
#define FZ_ENABLE_SPOT_RENDERING 1
|
||||
#endif
|
||||
|
||||
#if FZ_ENABLE_SPOT_RENDERING
|
||||
#undef FZ_PLOTTERS_N
|
||||
#define FZ_PLOTTERS_N 1
|
||||
#endif /* FZ_ENABLE_SPOT_RENDERING */
|
||||
|
||||
#ifndef FZ_PLOTTERS_G
|
||||
#define FZ_PLOTTERS_G 1
|
||||
#endif /* FZ_PLOTTERS_G */
|
||||
|
||||
#ifndef FZ_PLOTTERS_RGB
|
||||
#define FZ_PLOTTERS_RGB 1
|
||||
#endif /* FZ_PLOTTERS_RGB */
|
||||
|
||||
#ifndef FZ_PLOTTERS_CMYK
|
||||
#define FZ_PLOTTERS_CMYK 1
|
||||
#endif /* FZ_PLOTTERS_CMYK */
|
||||
|
||||
#ifndef FZ_PLOTTERS_N
|
||||
#define FZ_PLOTTERS_N 1
|
||||
#endif /* FZ_PLOTTERS_N */
|
||||
|
||||
/* We need at least 1 plotter defined */
|
||||
#if FZ_PLOTTERS_G == 0 && FZ_PLOTTERS_RGB == 0 && FZ_PLOTTERS_CMYK == 0
|
||||
#undef FZ_PLOTTERS_N
|
||||
#define FZ_PLOTTERS_N 1
|
||||
#endif
|
||||
|
||||
#ifndef FZ_ENABLE_PDF
|
||||
#define FZ_ENABLE_PDF 1
|
||||
#endif /* FZ_ENABLE_PDF */
|
||||
|
||||
#ifndef FZ_ENABLE_XPS
|
||||
#define FZ_ENABLE_XPS 1
|
||||
#endif /* FZ_ENABLE_XPS */
|
||||
|
||||
#ifndef FZ_ENABLE_SVG
|
||||
#define FZ_ENABLE_SVG 1
|
||||
#endif /* FZ_ENABLE_SVG */
|
||||
|
||||
#ifndef FZ_ENABLE_CBZ
|
||||
#define FZ_ENABLE_CBZ 1
|
||||
#endif /* FZ_ENABLE_CBZ */
|
||||
|
||||
#ifndef FZ_ENABLE_IMG
|
||||
#define FZ_ENABLE_IMG 1
|
||||
#endif /* FZ_ENABLE_IMG */
|
||||
|
||||
#ifndef FZ_ENABLE_HTML
|
||||
#define FZ_ENABLE_HTML 1
|
||||
#endif /* FZ_ENABLE_HTML */
|
||||
|
||||
#ifndef FZ_ENABLE_EPUB
|
||||
#define FZ_ENABLE_EPUB 1
|
||||
#endif /* FZ_ENABLE_EPUB */
|
||||
|
||||
#ifndef FZ_ENABLE_OCR_OUTPUT
|
||||
#define FZ_ENABLE_OCR_OUTPUT 1
|
||||
#endif /* FZ_ENABLE_OCR_OUTPUT */
|
||||
|
||||
#ifndef FZ_ENABLE_ODT_OUTPUT
|
||||
#define FZ_ENABLE_ODT_OUTPUT 1
|
||||
#endif /* FZ_ENABLE_ODT_OUTPUT */
|
||||
|
||||
#ifndef FZ_ENABLE_DOCX_OUTPUT
|
||||
#define FZ_ENABLE_DOCX_OUTPUT 1
|
||||
#endif /* FZ_ENABLE_DOCX_OUTPUT */
|
||||
|
||||
#ifndef FZ_ENABLE_JPX
|
||||
#define FZ_ENABLE_JPX 1
|
||||
#endif /* FZ_ENABLE_JPX */
|
||||
|
||||
#ifndef FZ_ENABLE_JS
|
||||
#define FZ_ENABLE_JS 1
|
||||
#endif /* FZ_ENABLE_JS */
|
||||
|
||||
#ifndef FZ_ENABLE_ICC
|
||||
#define FZ_ENABLE_ICC 1
|
||||
#endif /* FZ_ENABLE_ICC */
|
||||
|
||||
/* If Epub and HTML are both disabled, disable SIL fonts */
|
||||
#if FZ_ENABLE_HTML == 0 && FZ_ENABLE_EPUB == 0
|
||||
#undef TOFU_SIL
|
||||
#define TOFU_SIL
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_LEPTONICA) || !defined(HAVE_TESSERACT)
|
||||
#ifndef OCR_DISABLED
|
||||
#define OCR_DISABLED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* FZ_CONFIG_H */
|
||||
@@ -0,0 +1,942 @@
|
||||
// Copyright (C) 2004-2022 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_CONTEXT_H
|
||||
#define MUPDF_FITZ_CONTEXT_H
|
||||
|
||||
#include "mupdf/fitz/version.h"
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/geometry.h"
|
||||
|
||||
|
||||
#ifndef FZ_VERBOSE_EXCEPTIONS
|
||||
#define FZ_VERBOSE_EXCEPTIONS 0
|
||||
#endif
|
||||
|
||||
typedef struct fz_font_context fz_font_context;
|
||||
typedef struct fz_colorspace_context fz_colorspace_context;
|
||||
typedef struct fz_style_context fz_style_context;
|
||||
typedef struct fz_tuning_context fz_tuning_context;
|
||||
typedef struct fz_store fz_store;
|
||||
typedef struct fz_glyph_cache fz_glyph_cache;
|
||||
typedef struct fz_document_handler_context fz_document_handler_context;
|
||||
typedef struct fz_output fz_output;
|
||||
typedef struct fz_context fz_context;
|
||||
|
||||
/**
|
||||
Allocator structure; holds callbacks and private data pointer.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void *user;
|
||||
void *(*malloc)(void *, size_t);
|
||||
void *(*realloc)(void *, void *, size_t);
|
||||
void (*free)(void *, void *);
|
||||
} fz_alloc_context;
|
||||
|
||||
/**
|
||||
Exception macro definitions. Just treat these as a black box -
|
||||
pay no attention to the man behind the curtain.
|
||||
*/
|
||||
#define fz_var(var) fz_var_imp((void *)&(var))
|
||||
#define fz_try(ctx) if (!fz_setjmp(*fz_push_try(ctx))) if (fz_do_try(ctx)) do
|
||||
#define fz_always(ctx) while (0); if (fz_do_always(ctx)) do
|
||||
#define fz_catch(ctx) while (0); if (fz_do_catch(ctx))
|
||||
|
||||
/**
|
||||
These macros provide a simple exception handling system. Use them as
|
||||
follows:
|
||||
|
||||
fz_try(ctx)
|
||||
...
|
||||
fz_catch(ctx)
|
||||
...
|
||||
|
||||
or as:
|
||||
|
||||
fz_try(ctx)
|
||||
...
|
||||
fz_always(ctx)
|
||||
...
|
||||
fz_catch(ctx)
|
||||
...
|
||||
|
||||
Code within the fz_try() section can then throw exceptions using fz_throw()
|
||||
(or fz_vthrow()).
|
||||
|
||||
They are implemented with setjmp/longjmp, which can have unfortunate
|
||||
consequences for 'losing' local variable values on a throw. To avoid this
|
||||
we recommend calling 'fz_var(variable)' before the fz_try() for any
|
||||
local variable whose value may change within the fz_try() block and whose
|
||||
value will be required afterwards.
|
||||
|
||||
Do not call anything in the fz_always() section that can throw.
|
||||
|
||||
Any exception can be rethrown from the fz_catch() section using fz_rethrow()
|
||||
as long as there has been no intervening use of fz_try/fz_catch.
|
||||
*/
|
||||
|
||||
/**
|
||||
Throw an exception.
|
||||
|
||||
This assumes an enclosing fz_try() block within the callstack.
|
||||
*/
|
||||
FZ_NORETURN void fz_vthrow(fz_context *ctx, int errcode, const char *, va_list ap);
|
||||
FZ_NORETURN void fz_throw(fz_context *ctx, int errcode, const char *, ...) FZ_PRINTFLIKE(3,4);
|
||||
FZ_NORETURN void fz_rethrow(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Called within a catch block this modifies the current
|
||||
exception's code. If it's of type 'fromcode' it is
|
||||
modified to 'tocode'. Typically used for 'downgrading'
|
||||
exception severity.
|
||||
*/
|
||||
void fz_morph_error(fz_context *ctx, int fromcode, int tocode);
|
||||
|
||||
/**
|
||||
Log a warning.
|
||||
|
||||
This goes to the registered warning stream (stderr by
|
||||
default).
|
||||
*/
|
||||
void fz_vwarn(fz_context *ctx, const char *fmt, va_list ap);
|
||||
void fz_warn(fz_context *ctx, const char *fmt, ...) FZ_PRINTFLIKE(2,3);
|
||||
|
||||
/**
|
||||
Within an fz_catch() block, retrieve the formatted message
|
||||
string for the current exception.
|
||||
|
||||
This assumes no intervening use of fz_try/fz_catch.
|
||||
*/
|
||||
const char *fz_caught_message(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Within an fz_catch() block, retrieve the error code for
|
||||
the current exception.
|
||||
|
||||
This assumes no intervening use of fz_try/fz_catch.
|
||||
*/
|
||||
int fz_caught(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Within an fz_catch() block, rethrow the current exception
|
||||
if the errcode of the current exception matches.
|
||||
|
||||
This assumes no intervening use of fz_try/fz_catch.
|
||||
*/
|
||||
void fz_rethrow_if(fz_context *ctx, int errcode);
|
||||
|
||||
/**
|
||||
Format an error message, and log it to the registered
|
||||
error stream (stderr by default).
|
||||
*/
|
||||
void fz_log_error_printf(fz_context *ctx, const char *fmt, ...) FZ_PRINTFLIKE(2,3);
|
||||
void fz_vlog_error_printf(fz_context *ctx, const char *fmt, va_list ap);
|
||||
|
||||
/**
|
||||
Log a (preformatted) string to the registered
|
||||
error stream (stderr by default).
|
||||
*/
|
||||
void fz_log_error(fz_context *ctx, const char *str);
|
||||
|
||||
void fz_start_throw_on_repair(fz_context *ctx);
|
||||
void fz_end_throw_on_repair(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Now, a debugging feature. If FZ_VERBOSE_EXCEPTIONS is 1 then
|
||||
some of the above functions are replaced by versions that print
|
||||
FILE and LINE information.
|
||||
*/
|
||||
#if FZ_VERBOSE_EXCEPTIONS
|
||||
#define fz_vthrow(CTX, ERRCODE, FMT, VA) fz_vthrowFL(CTX, __FILE__, __LINE__, ERRCODE, FMT, VA)
|
||||
#define fz_throw(CTX, ERRCODE, ...) fz_throwFL(CTX, __FILE__, __LINE__, ERRCODE, __VA_ARGS__)
|
||||
#define fz_rethrow(CTX) fz_rethrowFL(CTX, __FILE__, __LINE__)
|
||||
#define fz_morph_error(CTX, FROM, TO) fz_morph_errorFL(CTX, __FILE__, __LINE__, FROM, TO)
|
||||
#define fz_vwarn(CTX, FMT, VA) fz_vwarnFL(CTX, __FILE__, __LINE__, FMT, VA)
|
||||
#define fz_warn(CTX, ...) fz_warnFL(CTX, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define fz_rethrow_if(CTX, ERRCODE) fz_rethrow_ifFL(CTX, __FILE__, __LINE__, ERRCODE)
|
||||
#define fz_log_error_printf(CTX, ...) fz_log_error_printfFL(CTX, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define fz_vlog_error_printf(CTX, FMT, VA) fz_log_error_printfFL(CTX, __FILE__, __LINE__, FMT, VA)
|
||||
#define fz_log_error(CTX, STR) fz_log_error_printfFL(CTX, __FILE__, __LINE__, STR)
|
||||
FZ_NORETURN void fz_vthrowFL(fz_context *ctx, const char *file, int line, int errcode, const char *fmt, va_list ap);
|
||||
FZ_NORETURN void fz_throwFL(fz_context *ctx, const char *file, int line, int errcode, const char *fmt, ...) FZ_PRINTFLIKE(5,6);
|
||||
FZ_NORETURN void fz_rethrowFL(fz_context *ctx, const char *file, int line);
|
||||
void fz_morph_errorFL(fz_context *ctx, const char *file, int line, int fromcode, int tocode);
|
||||
void fz_vwarnFL(fz_context *ctx, const char *file, int line, const char *fmt, va_list ap);
|
||||
void fz_warnFL(fz_context *ctx, const char *file, int line, const char *fmt, ...) FZ_PRINTFLIKE(4,5);
|
||||
void fz_rethrow_ifFL(fz_context *ctx, const char *file, int line, int errcode);
|
||||
void fz_log_error_printfFL(fz_context *ctx, const char *file, int line, const char *fmt, ...) FZ_PRINTFLIKE(4,5);
|
||||
void fz_vlog_error_printfFL(fz_context *ctx, const char *file, int line, const char *fmt, va_list ap);
|
||||
void fz_log_errorFL(fz_context *ctx, const char *file, int line, const char *str);
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
FZ_ERROR_NONE = 0,
|
||||
FZ_ERROR_MEMORY = 1,
|
||||
FZ_ERROR_GENERIC = 2,
|
||||
FZ_ERROR_SYNTAX = 3,
|
||||
FZ_ERROR_MINOR = 4,
|
||||
FZ_ERROR_TRYLATER = 5,
|
||||
FZ_ERROR_ABORT = 6,
|
||||
FZ_ERROR_REPAIRED = 7,
|
||||
FZ_ERROR_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
Flush any repeated warnings.
|
||||
|
||||
Repeated warnings are buffered, counted and eventually printed
|
||||
along with the number of repetitions. Call fz_flush_warnings
|
||||
to force printing of the latest buffered warning and the
|
||||
number of repetitions, for example to make sure that all
|
||||
warnings are printed before exiting an application.
|
||||
*/
|
||||
void fz_flush_warnings(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Locking functions
|
||||
|
||||
MuPDF is kept deliberately free of any knowledge of particular
|
||||
threading systems. As such, in order for safe multi-threaded
|
||||
operation, we rely on callbacks to client provided functions.
|
||||
|
||||
A client is expected to provide FZ_LOCK_MAX number of mutexes,
|
||||
and a function to lock/unlock each of them. These may be
|
||||
recursive mutexes, but do not have to be.
|
||||
|
||||
If a client does not intend to use multiple threads, then it
|
||||
may pass NULL instead of a lock structure.
|
||||
|
||||
In order to avoid deadlocks, we have one simple rule
|
||||
internally as to how we use locks: We can never take lock n
|
||||
when we already hold any lock i, where 0 <= i <= n. In order
|
||||
to verify this, we have some debugging code, that can be
|
||||
enabled by defining FITZ_DEBUG_LOCKING.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *user;
|
||||
void (*lock)(void *user, int lock);
|
||||
void (*unlock)(void *user, int lock);
|
||||
} fz_locks_context;
|
||||
|
||||
enum {
|
||||
FZ_LOCK_ALLOC = 0,
|
||||
FZ_LOCK_FREETYPE,
|
||||
FZ_LOCK_GLYPHCACHE,
|
||||
FZ_LOCK_MAX
|
||||
};
|
||||
|
||||
#if defined(MEMENTO) || !defined(NDEBUG)
|
||||
#define FITZ_DEBUG_LOCKING
|
||||
#endif
|
||||
|
||||
#ifdef FITZ_DEBUG_LOCKING
|
||||
|
||||
void fz_assert_lock_held(fz_context *ctx, int lock);
|
||||
void fz_assert_lock_not_held(fz_context *ctx, int lock);
|
||||
void fz_lock_debug_lock(fz_context *ctx, int lock);
|
||||
void fz_lock_debug_unlock(fz_context *ctx, int lock);
|
||||
|
||||
#else
|
||||
|
||||
#define fz_assert_lock_held(A,B) do { } while (0)
|
||||
#define fz_assert_lock_not_held(A,B) do { } while (0)
|
||||
#define fz_lock_debug_lock(A,B) do { } while (0)
|
||||
#define fz_lock_debug_unlock(A,B) do { } while (0)
|
||||
|
||||
#endif /* !FITZ_DEBUG_LOCKING */
|
||||
|
||||
/**
|
||||
Specifies the maximum size in bytes of the resource store in
|
||||
fz_context. Given as argument to fz_new_context.
|
||||
|
||||
FZ_STORE_UNLIMITED: Let resource store grow unbounded.
|
||||
|
||||
FZ_STORE_DEFAULT: A reasonable upper bound on the size, for
|
||||
devices that are not memory constrained.
|
||||
*/
|
||||
enum {
|
||||
FZ_STORE_UNLIMITED = 0,
|
||||
FZ_STORE_DEFAULT = 256 << 20,
|
||||
};
|
||||
|
||||
/**
|
||||
Allocate context containing global state.
|
||||
|
||||
The global state contains an exception stack, resource store,
|
||||
etc. Most functions in MuPDF take a context argument to be
|
||||
able to reference the global state. See fz_drop_context for
|
||||
freeing an allocated context.
|
||||
|
||||
alloc: Supply a custom memory allocator through a set of
|
||||
function pointers. Set to NULL for the standard library
|
||||
allocator. The context will keep the allocator pointer, so the
|
||||
data it points to must not be modified or freed during the
|
||||
lifetime of the context.
|
||||
|
||||
locks: Supply a set of locks and functions to lock/unlock
|
||||
them, intended for multi-threaded applications. Set to NULL
|
||||
when using MuPDF in a single-threaded applications. The
|
||||
context will keep the locks pointer, so the data it points to
|
||||
must not be modified or freed during the lifetime of the
|
||||
context.
|
||||
|
||||
max_store: Maximum size in bytes of the resource store, before
|
||||
it will start evicting cached resources such as fonts and
|
||||
images. FZ_STORE_UNLIMITED can be used if a hard limit is not
|
||||
desired. Use FZ_STORE_DEFAULT to get a reasonable size.
|
||||
|
||||
May return NULL.
|
||||
*/
|
||||
#define fz_new_context(alloc, locks, max_store) fz_new_context_imp(alloc, locks, max_store, FZ_VERSION)
|
||||
|
||||
/**
|
||||
Make a clone of an existing context.
|
||||
|
||||
This function is meant to be used in multi-threaded
|
||||
applications where each thread requires its own context, yet
|
||||
parts of the global state, for example caching, are shared.
|
||||
|
||||
ctx: Context obtained from fz_new_context to make a copy of.
|
||||
ctx must have had locks and lock/functions setup when created.
|
||||
The two contexts will share the memory allocator, resource
|
||||
store, locks and lock/unlock functions. They will each have
|
||||
their own exception stacks though.
|
||||
|
||||
May return NULL.
|
||||
*/
|
||||
fz_context *fz_clone_context(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Free a context and its global state.
|
||||
|
||||
The context and all of its global state is freed, and any
|
||||
buffered warnings are flushed (see fz_flush_warnings). If NULL
|
||||
is passed in nothing will happen.
|
||||
|
||||
Must not be called for a context that is being used in an active
|
||||
fz_try(), fz_always() or fz_catch() block.
|
||||
*/
|
||||
void fz_drop_context(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Set the user field in the context.
|
||||
|
||||
NULL initially, this field can be set to any opaque value
|
||||
required by the user. It is copied on clones.
|
||||
*/
|
||||
void fz_set_user_context(fz_context *ctx, void *user);
|
||||
|
||||
/**
|
||||
Read the user field from the context.
|
||||
*/
|
||||
void *fz_user_context(fz_context *ctx);
|
||||
|
||||
/**
|
||||
FIXME: Better not to expose fz_default_error_callback, and
|
||||
fz_default_warning callback and to allow 'NULL' to be used
|
||||
int fz_set_xxxx_callback to mean "defaults".
|
||||
|
||||
FIXME: Do we need/want functions like
|
||||
fz_error_callback(ctx, message) to allow callers to inject
|
||||
stuff into the error/warning streams?
|
||||
*/
|
||||
/**
|
||||
The default error callback. Declared publicly just so that the
|
||||
error callback can be set back to this after it has been
|
||||
overridden.
|
||||
*/
|
||||
void fz_default_error_callback(void *user, const char *message);
|
||||
|
||||
/**
|
||||
The default warning callback. Declared publicly just so that
|
||||
the warning callback can be set back to this after it has been
|
||||
overridden.
|
||||
*/
|
||||
void fz_default_warning_callback(void *user, const char *message);
|
||||
|
||||
/**
|
||||
A callback called whenever an error message is generated.
|
||||
The user pointer passed to fz_set_error_callback() is passed
|
||||
along with the error message.
|
||||
*/
|
||||
typedef void (fz_error_cb)(void *user, const char *message);
|
||||
|
||||
/**
|
||||
A callback called whenever a warning message is generated.
|
||||
The user pointer passed to fz_set_warning_callback() is
|
||||
passed along with the warning message.
|
||||
*/
|
||||
typedef void (fz_warning_cb)(void *user, const char *message);
|
||||
|
||||
/**
|
||||
Set the error callback. This will be called as part of the
|
||||
exception handling.
|
||||
|
||||
The callback must not throw exceptions!
|
||||
*/
|
||||
void fz_set_error_callback(fz_context *ctx, fz_error_cb *error_cb, void *user);
|
||||
|
||||
/**
|
||||
Retrieve the currently set error callback, or NULL if none
|
||||
has been set. Optionally, if user is non-NULL, the user pointer
|
||||
given when the warning callback was set is also passed back to
|
||||
the caller.
|
||||
*/
|
||||
fz_error_cb *fz_error_callback(fz_context *ctx, void **user);
|
||||
|
||||
/**
|
||||
Set the warning callback. This will be called as part of the
|
||||
exception handling.
|
||||
|
||||
The callback must not throw exceptions!
|
||||
*/
|
||||
void fz_set_warning_callback(fz_context *ctx, fz_warning_cb *warning_cb, void *user);
|
||||
|
||||
/**
|
||||
Retrieve the currently set warning callback, or NULL if none
|
||||
has been set. Optionally, if user is non-NULL, the user pointer
|
||||
given when the warning callback was set is also passed back to
|
||||
the caller.
|
||||
*/
|
||||
fz_warning_cb *fz_warning_callback(fz_context *ctx, void **user);
|
||||
|
||||
/**
|
||||
In order to tune MuPDF's behaviour, certain functions can
|
||||
(optionally) be provided by callers.
|
||||
*/
|
||||
|
||||
/**
|
||||
Given the width and height of an image,
|
||||
the subsample factor, and the subarea of the image actually
|
||||
required, the caller can decide whether to decode the whole
|
||||
image or just a subarea.
|
||||
|
||||
arg: The caller supplied opaque argument.
|
||||
|
||||
w, h: The width/height of the complete image.
|
||||
|
||||
l2factor: The log2 factor for subsampling (i.e. image will be
|
||||
decoded to (w>>l2factor, h>>l2factor)).
|
||||
|
||||
subarea: The actual subarea required for the current operation.
|
||||
The tuning function is allowed to increase this in size if
|
||||
required.
|
||||
*/
|
||||
typedef void (fz_tune_image_decode_fn)(void *arg, int w, int h, int l2factor, fz_irect *subarea);
|
||||
|
||||
/**
|
||||
Given the source width and height of
|
||||
image, together with the actual required width and height,
|
||||
decide whether we should use mitchell scaling.
|
||||
|
||||
arg: The caller supplied opaque argument.
|
||||
|
||||
dst_w, dst_h: The actual width/height required on the target
|
||||
device.
|
||||
|
||||
src_w, src_h: The source width/height of the image.
|
||||
|
||||
Return 0 not to use the Mitchell scaler, 1 to use the Mitchell
|
||||
scaler. All other values reserved.
|
||||
*/
|
||||
typedef int (fz_tune_image_scale_fn)(void *arg, int dst_w, int dst_h, int src_w, int src_h);
|
||||
|
||||
/**
|
||||
Set the tuning function to use for
|
||||
image decode.
|
||||
|
||||
image_decode: Function to use.
|
||||
|
||||
arg: Opaque argument to be passed to tuning function.
|
||||
*/
|
||||
void fz_tune_image_decode(fz_context *ctx, fz_tune_image_decode_fn *image_decode, void *arg);
|
||||
|
||||
/**
|
||||
Set the tuning function to use for
|
||||
image scaling.
|
||||
|
||||
image_scale: Function to use.
|
||||
|
||||
arg: Opaque argument to be passed to tuning function.
|
||||
*/
|
||||
void fz_tune_image_scale(fz_context *ctx, fz_tune_image_scale_fn *image_scale, void *arg);
|
||||
|
||||
/**
|
||||
Get the number of bits of antialiasing we are
|
||||
using (for graphics). Between 0 and 8.
|
||||
*/
|
||||
int fz_aa_level(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Set the number of bits of antialiasing we should
|
||||
use (for both text and graphics).
|
||||
|
||||
bits: The number of bits of antialiasing to use (values are
|
||||
clamped to within the 0 to 8 range).
|
||||
*/
|
||||
void fz_set_aa_level(fz_context *ctx, int bits);
|
||||
|
||||
/**
|
||||
Get the number of bits of antialiasing we are
|
||||
using for text. Between 0 and 8.
|
||||
*/
|
||||
int fz_text_aa_level(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Set the number of bits of antialiasing we
|
||||
should use for text.
|
||||
|
||||
bits: The number of bits of antialiasing to use (values are
|
||||
clamped to within the 0 to 8 range).
|
||||
*/
|
||||
void fz_set_text_aa_level(fz_context *ctx, int bits);
|
||||
|
||||
/**
|
||||
Get the number of bits of antialiasing we are
|
||||
using for graphics. Between 0 and 8.
|
||||
*/
|
||||
int fz_graphics_aa_level(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Set the number of bits of antialiasing we
|
||||
should use for graphics.
|
||||
|
||||
bits: The number of bits of antialiasing to use (values are
|
||||
clamped to within the 0 to 8 range).
|
||||
*/
|
||||
void fz_set_graphics_aa_level(fz_context *ctx, int bits);
|
||||
|
||||
/**
|
||||
Get the minimum line width to be
|
||||
used for stroked lines.
|
||||
|
||||
min_line_width: The minimum line width to use (in pixels).
|
||||
*/
|
||||
float fz_graphics_min_line_width(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Set the minimum line width to be
|
||||
used for stroked lines.
|
||||
|
||||
min_line_width: The minimum line width to use (in pixels).
|
||||
*/
|
||||
void fz_set_graphics_min_line_width(fz_context *ctx, float min_line_width);
|
||||
|
||||
/**
|
||||
Get the user stylesheet source text.
|
||||
*/
|
||||
const char *fz_user_css(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Set the user stylesheet source text for use with HTML and EPUB.
|
||||
*/
|
||||
void fz_set_user_css(fz_context *ctx, const char *text);
|
||||
|
||||
/**
|
||||
Return whether to respect document styles in HTML and EPUB.
|
||||
*/
|
||||
int fz_use_document_css(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Toggle whether to respect document styles in HTML and EPUB.
|
||||
*/
|
||||
void fz_set_use_document_css(fz_context *ctx, int use);
|
||||
|
||||
/**
|
||||
Enable icc profile based operation.
|
||||
*/
|
||||
void fz_enable_icc(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Disable icc profile based operation.
|
||||
*/
|
||||
void fz_disable_icc(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Memory Allocation and Scavenging:
|
||||
|
||||
All calls to MuPDF's allocator functions pass through to the
|
||||
underlying allocators passed in when the initial context is
|
||||
created, after locks are taken (using the supplied locking
|
||||
function) to ensure that only one thread at a time calls
|
||||
through.
|
||||
|
||||
If the underlying allocator fails, MuPDF attempts to make room
|
||||
for the allocation by evicting elements from the store, then
|
||||
retrying.
|
||||
|
||||
Any call to allocate may then result in several calls to the
|
||||
underlying allocator, and result in elements that are only
|
||||
referred to by the store being freed.
|
||||
*/
|
||||
|
||||
/**
|
||||
Allocate memory for a structure, clear it, and tag the pointer
|
||||
for Memento.
|
||||
|
||||
Throws exception in the event of failure to allocate.
|
||||
*/
|
||||
#define fz_malloc_struct(CTX, TYPE) \
|
||||
((TYPE*)Memento_label(fz_calloc(CTX, 1, sizeof(TYPE)), #TYPE))
|
||||
|
||||
/**
|
||||
Allocate memory for an array of structures, clear it, and tag
|
||||
the pointer for Memento.
|
||||
|
||||
Throws exception in the event of failure to allocate.
|
||||
*/
|
||||
#define fz_malloc_struct_array(CTX, N, TYPE) \
|
||||
((TYPE*)Memento_label(fz_calloc(CTX, N, sizeof(TYPE)), #TYPE "[]"))
|
||||
|
||||
/**
|
||||
Allocate uninitialized memory for an array of structures, and
|
||||
tag the pointer for Memento. Does NOT clear the memory!
|
||||
|
||||
Throws exception in the event of failure to allocate.
|
||||
*/
|
||||
#define fz_malloc_array(CTX, COUNT, TYPE) \
|
||||
((TYPE*)Memento_label(fz_malloc(CTX, (COUNT) * sizeof(TYPE)), #TYPE "[]"))
|
||||
#define fz_realloc_array(CTX, OLD, COUNT, TYPE) \
|
||||
((TYPE*)Memento_label(fz_realloc(CTX, OLD, (COUNT) * sizeof(TYPE)), #TYPE "[]"))
|
||||
|
||||
/**
|
||||
Allocate uninitialized memory of a given size.
|
||||
Does NOT clear the memory!
|
||||
|
||||
May return NULL for size = 0.
|
||||
|
||||
Throws exception in the event of failure to allocate.
|
||||
*/
|
||||
void *fz_malloc(fz_context *ctx, size_t size);
|
||||
|
||||
/**
|
||||
Allocate array of memory of count entries of size bytes.
|
||||
Clears the memory to zero.
|
||||
|
||||
Throws exception in the event of failure to allocate.
|
||||
*/
|
||||
void *fz_calloc(fz_context *ctx, size_t count, size_t size);
|
||||
|
||||
/**
|
||||
Reallocates a block of memory to given size. Existing contents
|
||||
up to min(old_size,new_size) are maintained. The rest of the
|
||||
block is uninitialised.
|
||||
|
||||
fz_realloc(ctx, NULL, size) behaves like fz_malloc(ctx, size).
|
||||
|
||||
fz_realloc(ctx, p, 0); behaves like fz_free(ctx, p).
|
||||
|
||||
Throws exception in the event of failure to allocate.
|
||||
*/
|
||||
void *fz_realloc(fz_context *ctx, void *p, size_t size);
|
||||
|
||||
/**
|
||||
Free a previously allocated block of memory.
|
||||
|
||||
fz_free(ctx, NULL) does nothing.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_free(fz_context *ctx, void *p);
|
||||
|
||||
/**
|
||||
fz_malloc equivalent that returns NULL rather than throwing
|
||||
exceptions.
|
||||
*/
|
||||
void *fz_malloc_no_throw(fz_context *ctx, size_t size);
|
||||
|
||||
/**
|
||||
fz_calloc equivalent that returns NULL rather than throwing
|
||||
exceptions.
|
||||
*/
|
||||
void *fz_calloc_no_throw(fz_context *ctx, size_t count, size_t size);
|
||||
|
||||
/**
|
||||
fz_realloc equivalent that returns NULL rather than throwing
|
||||
exceptions.
|
||||
*/
|
||||
void *fz_realloc_no_throw(fz_context *ctx, void *p, size_t size);
|
||||
|
||||
/**
|
||||
Portable strdup implementation, using fz allocators.
|
||||
*/
|
||||
char *fz_strdup(fz_context *ctx, const char *s);
|
||||
|
||||
/**
|
||||
Fill block with len bytes of pseudo-randomness.
|
||||
*/
|
||||
void fz_memrnd(fz_context *ctx, uint8_t *block, int len);
|
||||
|
||||
|
||||
/* Implementation details: subject to change. */
|
||||
|
||||
/* Implementations exposed for speed, but considered private. */
|
||||
|
||||
void fz_var_imp(void *);
|
||||
fz_jmp_buf *fz_push_try(fz_context *ctx);
|
||||
int fz_do_try(fz_context *ctx);
|
||||
int fz_do_always(fz_context *ctx);
|
||||
int fz_do_catch(fz_context *ctx);
|
||||
|
||||
#ifndef FZ_JMPBUF_ALIGN
|
||||
#define FZ_JMPBUF_ALIGN 32
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fz_jmp_buf buffer;
|
||||
int state, code;
|
||||
char padding[FZ_JMPBUF_ALIGN-sizeof(int)*2];
|
||||
} fz_error_stack_slot;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fz_error_stack_slot *top;
|
||||
fz_error_stack_slot stack[256];
|
||||
fz_error_stack_slot padding;
|
||||
fz_error_stack_slot *stack_base;
|
||||
int errcode;
|
||||
void *print_user;
|
||||
void (*print)(void *user, const char *message);
|
||||
char message[256];
|
||||
} fz_error_context;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *print_user;
|
||||
void (*print)(void *user, const char *message);
|
||||
int count;
|
||||
char message[256];
|
||||
} fz_warn_context;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int hscale;
|
||||
int vscale;
|
||||
int scale;
|
||||
int bits;
|
||||
int text_bits;
|
||||
float min_line_width;
|
||||
} fz_aa_context;
|
||||
|
||||
struct fz_context
|
||||
{
|
||||
void *user;
|
||||
fz_alloc_context alloc;
|
||||
fz_locks_context locks;
|
||||
fz_error_context error;
|
||||
fz_warn_context warn;
|
||||
|
||||
/* unshared contexts */
|
||||
fz_aa_context aa;
|
||||
uint16_t seed48[7];
|
||||
#if FZ_ENABLE_ICC
|
||||
int icc_enabled;
|
||||
#endif
|
||||
int throw_on_repair;
|
||||
|
||||
/* TODO: should these be unshared? */
|
||||
fz_document_handler_context *handler;
|
||||
fz_style_context *style;
|
||||
fz_tuning_context *tuning;
|
||||
|
||||
/* shared contexts */
|
||||
fz_output *stddbg;
|
||||
fz_font_context *font;
|
||||
fz_colorspace_context *colorspace;
|
||||
fz_store *store;
|
||||
fz_glyph_cache *glyph_cache;
|
||||
};
|
||||
|
||||
fz_context *fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks, size_t max_store, const char *version);
|
||||
|
||||
/**
|
||||
Lock one of the user supplied mutexes.
|
||||
*/
|
||||
static inline void
|
||||
fz_lock(fz_context *ctx, int lock)
|
||||
{
|
||||
fz_lock_debug_lock(ctx, lock);
|
||||
ctx->locks.lock(ctx->locks.user, lock);
|
||||
}
|
||||
|
||||
/**
|
||||
Unlock one of the user supplied mutexes.
|
||||
*/
|
||||
static inline void
|
||||
fz_unlock(fz_context *ctx, int lock)
|
||||
{
|
||||
fz_lock_debug_unlock(ctx, lock);
|
||||
ctx->locks.unlock(ctx->locks.user, lock);
|
||||
}
|
||||
|
||||
/* Lock-safe reference counting functions */
|
||||
|
||||
static inline void *
|
||||
fz_keep_imp(fz_context *ctx, void *p, int *refs)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
(void)Memento_checkIntPointerOrNull(refs);
|
||||
fz_lock(ctx, FZ_LOCK_ALLOC);
|
||||
if (*refs > 0)
|
||||
{
|
||||
(void)Memento_takeRef(p);
|
||||
++*refs;
|
||||
}
|
||||
fz_unlock(ctx, FZ_LOCK_ALLOC);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
fz_keep_imp_locked(fz_context *ctx FZ_UNUSED, void *p, int *refs)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
(void)Memento_checkIntPointerOrNull(refs);
|
||||
if (*refs > 0)
|
||||
{
|
||||
(void)Memento_takeRef(p);
|
||||
++*refs;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
fz_keep_imp8_locked(fz_context *ctx FZ_UNUSED, void *p, int8_t *refs)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
(void)Memento_checkIntPointerOrNull(refs);
|
||||
if (*refs > 0)
|
||||
{
|
||||
(void)Memento_takeRef(p);
|
||||
++*refs;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
fz_keep_imp8(fz_context *ctx, void *p, int8_t *refs)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
(void)Memento_checkBytePointerOrNull(refs);
|
||||
fz_lock(ctx, FZ_LOCK_ALLOC);
|
||||
if (*refs > 0)
|
||||
{
|
||||
(void)Memento_takeRef(p);
|
||||
++*refs;
|
||||
}
|
||||
fz_unlock(ctx, FZ_LOCK_ALLOC);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
fz_keep_imp16(fz_context *ctx, void *p, int16_t *refs)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
(void)Memento_checkShortPointerOrNull(refs);
|
||||
fz_lock(ctx, FZ_LOCK_ALLOC);
|
||||
if (*refs > 0)
|
||||
{
|
||||
(void)Memento_takeRef(p);
|
||||
++*refs;
|
||||
}
|
||||
fz_unlock(ctx, FZ_LOCK_ALLOC);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline int
|
||||
fz_drop_imp(fz_context *ctx, void *p, int *refs)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
int drop;
|
||||
(void)Memento_checkIntPointerOrNull(refs);
|
||||
fz_lock(ctx, FZ_LOCK_ALLOC);
|
||||
if (*refs > 0)
|
||||
{
|
||||
(void)Memento_dropIntRef(p);
|
||||
drop = --*refs == 0;
|
||||
}
|
||||
else
|
||||
drop = 0;
|
||||
fz_unlock(ctx, FZ_LOCK_ALLOC);
|
||||
return drop;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
fz_drop_imp8(fz_context *ctx, void *p, int8_t *refs)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
int drop;
|
||||
(void)Memento_checkBytePointerOrNull(refs);
|
||||
fz_lock(ctx, FZ_LOCK_ALLOC);
|
||||
if (*refs > 0)
|
||||
{
|
||||
(void)Memento_dropByteRef(p);
|
||||
drop = --*refs == 0;
|
||||
}
|
||||
else
|
||||
drop = 0;
|
||||
fz_unlock(ctx, FZ_LOCK_ALLOC);
|
||||
return drop;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
fz_drop_imp16(fz_context *ctx, void *p, int16_t *refs)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
int drop;
|
||||
(void)Memento_checkShortPointerOrNull(refs);
|
||||
fz_lock(ctx, FZ_LOCK_ALLOC);
|
||||
if (*refs > 0)
|
||||
{
|
||||
(void)Memento_dropShortRef(p);
|
||||
drop = --*refs == 0;
|
||||
}
|
||||
else
|
||||
drop = 0;
|
||||
fz_unlock(ctx, FZ_LOCK_ALLOC);
|
||||
return drop;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,270 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_CRYPT_H
|
||||
#define MUPDF_FITZ_CRYPT_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
|
||||
/* md5 digests */
|
||||
|
||||
/**
|
||||
Structure definition is public to enable stack
|
||||
based allocation. Do not access the members directly.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t lo, hi;
|
||||
uint32_t a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
} fz_md5;
|
||||
|
||||
/**
|
||||
MD5 initialization. Begins an MD5 operation, writing a new
|
||||
context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_md5_init(fz_md5 *state);
|
||||
|
||||
/**
|
||||
MD5 block update operation. Continues an MD5 message-digest
|
||||
operation, processing another message block, and updating the
|
||||
context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_md5_update(fz_md5 *state, const unsigned char *input, size_t inlen);
|
||||
|
||||
/**
|
||||
MD5 block update operation. Continues an MD5 message-digest
|
||||
operation, processing an int64, and updating the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_md5_update_int64(fz_md5 *state, int64_t i);
|
||||
|
||||
/**
|
||||
MD5 finalization. Ends an MD5 message-digest operation, writing
|
||||
the message digest and zeroizing the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_md5_final(fz_md5 *state, unsigned char digest[16]);
|
||||
|
||||
/* sha-256 digests */
|
||||
|
||||
/**
|
||||
Structure definition is public to enable stack
|
||||
based allocation. Do not access the members directly.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int state[8];
|
||||
unsigned int count[2];
|
||||
union {
|
||||
unsigned char u8[64];
|
||||
unsigned int u32[16];
|
||||
} buffer;
|
||||
} fz_sha256;
|
||||
|
||||
/**
|
||||
SHA256 initialization. Begins an SHA256 operation, initialising
|
||||
the supplied context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha256_init(fz_sha256 *state);
|
||||
|
||||
/**
|
||||
SHA256 block update operation. Continues an SHA256 message-
|
||||
digest operation, processing another message block, and updating
|
||||
the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha256_update(fz_sha256 *state, const unsigned char *input, size_t inlen);
|
||||
|
||||
/**
|
||||
MD5 finalization. Ends an MD5 message-digest operation, writing
|
||||
the message digest and zeroizing the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]);
|
||||
|
||||
/* sha-512 digests */
|
||||
|
||||
/**
|
||||
Structure definition is public to enable stack
|
||||
based allocation. Do not access the members directly.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t state[8];
|
||||
unsigned int count[2];
|
||||
union {
|
||||
unsigned char u8[128];
|
||||
uint64_t u64[16];
|
||||
} buffer;
|
||||
} fz_sha512;
|
||||
|
||||
/**
|
||||
SHA512 initialization. Begins an SHA512 operation, initialising
|
||||
the supplied context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha512_init(fz_sha512 *state);
|
||||
|
||||
/**
|
||||
SHA512 block update operation. Continues an SHA512 message-
|
||||
digest operation, processing another message block, and updating
|
||||
the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha512_update(fz_sha512 *state, const unsigned char *input, size_t inlen);
|
||||
|
||||
/**
|
||||
SHA512 finalization. Ends an SHA512 message-digest operation,
|
||||
writing the message digest and zeroizing the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha512_final(fz_sha512 *state, unsigned char digest[64]);
|
||||
|
||||
/* sha-384 digests */
|
||||
|
||||
typedef fz_sha512 fz_sha384;
|
||||
|
||||
/**
|
||||
SHA384 initialization. Begins an SHA384 operation, initialising
|
||||
the supplied context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha384_init(fz_sha384 *state);
|
||||
|
||||
/**
|
||||
SHA384 block update operation. Continues an SHA384 message-
|
||||
digest operation, processing another message block, and updating
|
||||
the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha384_update(fz_sha384 *state, const unsigned char *input, size_t inlen);
|
||||
|
||||
/**
|
||||
SHA384 finalization. Ends an SHA384 message-digest operation,
|
||||
writing the message digest and zeroizing the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_sha384_final(fz_sha384 *state, unsigned char digest[64]);
|
||||
|
||||
/* arc4 crypto */
|
||||
|
||||
/**
|
||||
Structure definition is public to enable stack
|
||||
based allocation. Do not access the members directly.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned x;
|
||||
unsigned y;
|
||||
unsigned char state[256];
|
||||
} fz_arc4;
|
||||
|
||||
/**
|
||||
RC4 initialization. Begins an RC4 operation, writing a new
|
||||
context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_arc4_init(fz_arc4 *state, const unsigned char *key, size_t len);
|
||||
|
||||
/**
|
||||
RC4 block encrypt operation; encrypt src into dst (both of
|
||||
length len) updating the RC4 state as we go.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, size_t len);
|
||||
|
||||
/**
|
||||
RC4 finalization. Zero the context.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_arc4_final(fz_arc4 *state);
|
||||
|
||||
/* AES block cipher implementation from XYSSL */
|
||||
|
||||
/**
|
||||
Structure definitions are public to enable stack
|
||||
based allocation. Do not access the members directly.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nr; /* number of rounds */
|
||||
uint32_t *rk; /* AES round keys */
|
||||
uint32_t buf[68]; /* unaligned data */
|
||||
} fz_aes;
|
||||
|
||||
#define FZ_AES_DECRYPT 0
|
||||
#define FZ_AES_ENCRYPT 1
|
||||
|
||||
/**
|
||||
AES encryption intialisation. Fills in the supplied context
|
||||
and prepares for encryption using the given key.
|
||||
|
||||
Returns non-zero for error (key size other than 128/192/256).
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
int fz_aes_setkey_enc(fz_aes *ctx, const unsigned char *key, int keysize);
|
||||
|
||||
/**
|
||||
AES decryption intialisation. Fills in the supplied context
|
||||
and prepares for decryption using the given key.
|
||||
|
||||
Returns non-zero for error (key size other than 128/192/256).
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
int fz_aes_setkey_dec(fz_aes *ctx, const unsigned char *key, int keysize);
|
||||
|
||||
/**
|
||||
AES block processing. Encrypts or Decrypts (according to mode,
|
||||
which must match what was initially set up) length bytes (which
|
||||
must be a multiple of 16), using (and modifying) the insertion
|
||||
vector iv, reading from input, and writing to output.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_aes_crypt_cbc(fz_aes *ctx, int mode, size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,595 @@
|
||||
// Copyright (C) 2004-2023 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_DEVICE_H
|
||||
#define MUPDF_FITZ_DEVICE_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/geometry.h"
|
||||
#include "mupdf/fitz/image.h"
|
||||
#include "mupdf/fitz/shade.h"
|
||||
#include "mupdf/fitz/path.h"
|
||||
#include "mupdf/fitz/text.h"
|
||||
|
||||
/**
|
||||
The different format handlers (pdf, xps etc) interpret pages to
|
||||
a device. These devices can then process the stream of calls
|
||||
they receive in various ways:
|
||||
The trace device outputs debugging information for the calls.
|
||||
The draw device will render them.
|
||||
The list device stores them in a list to play back later.
|
||||
The text device performs text extraction and searching.
|
||||
The bbox device calculates the bounding box for the page.
|
||||
Other devices can (and will) be written in the future.
|
||||
*/
|
||||
typedef struct fz_device fz_device;
|
||||
|
||||
enum
|
||||
{
|
||||
/* Flags */
|
||||
FZ_DEVFLAG_MASK = 1,
|
||||
FZ_DEVFLAG_COLOR = 2,
|
||||
FZ_DEVFLAG_UNCACHEABLE = 4,
|
||||
FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8,
|
||||
FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16,
|
||||
FZ_DEVFLAG_STARTCAP_UNDEFINED = 32,
|
||||
FZ_DEVFLAG_DASHCAP_UNDEFINED = 64,
|
||||
FZ_DEVFLAG_ENDCAP_UNDEFINED = 128,
|
||||
FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256,
|
||||
FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512,
|
||||
FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024,
|
||||
/* Arguably we should have a bit for the dash pattern itself
|
||||
* being undefined, but that causes problems; do we assume that
|
||||
* it should always be set to non-dashing at the start of every
|
||||
* glyph? */
|
||||
FZ_DEVFLAG_BBOX_DEFINED = 2048,
|
||||
FZ_DEVFLAG_GRIDFIT_AS_TILED = 4096,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/* PDF 1.4 -- standard separable */
|
||||
FZ_BLEND_NORMAL,
|
||||
FZ_BLEND_MULTIPLY,
|
||||
FZ_BLEND_SCREEN,
|
||||
FZ_BLEND_OVERLAY,
|
||||
FZ_BLEND_DARKEN,
|
||||
FZ_BLEND_LIGHTEN,
|
||||
FZ_BLEND_COLOR_DODGE,
|
||||
FZ_BLEND_COLOR_BURN,
|
||||
FZ_BLEND_HARD_LIGHT,
|
||||
FZ_BLEND_SOFT_LIGHT,
|
||||
FZ_BLEND_DIFFERENCE,
|
||||
FZ_BLEND_EXCLUSION,
|
||||
|
||||
/* PDF 1.4 -- standard non-separable */
|
||||
FZ_BLEND_HUE,
|
||||
FZ_BLEND_SATURATION,
|
||||
FZ_BLEND_COLOR,
|
||||
FZ_BLEND_LUMINOSITY,
|
||||
|
||||
/* For packing purposes */
|
||||
FZ_BLEND_MODEMASK = 15,
|
||||
FZ_BLEND_ISOLATED = 16,
|
||||
FZ_BLEND_KNOCKOUT = 32
|
||||
};
|
||||
|
||||
/**
|
||||
Map from (case sensitive) blend mode string to enumeration.
|
||||
*/
|
||||
int fz_lookup_blendmode(const char *name);
|
||||
|
||||
/**
|
||||
Map from enumeration to blend mode string.
|
||||
|
||||
The string is static, with arbitrary lifespan.
|
||||
*/
|
||||
const char *fz_blendmode_name(int blendmode);
|
||||
|
||||
/**
|
||||
The device structure is public to allow devices to be
|
||||
implemented outside of fitz.
|
||||
|
||||
Device methods should always be called using e.g.
|
||||
fz_fill_path(ctx, dev, ...) rather than
|
||||
dev->fill_path(ctx, dev, ...)
|
||||
*/
|
||||
|
||||
/**
|
||||
Devices can keep track of containers (clips/masks/groups/tiles)
|
||||
as they go to save callers having to do it.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
fz_rect scissor;
|
||||
int type;
|
||||
int user;
|
||||
} fz_device_container_stack;
|
||||
|
||||
enum
|
||||
{
|
||||
fz_device_container_stack_is_clip,
|
||||
fz_device_container_stack_is_mask,
|
||||
fz_device_container_stack_is_group,
|
||||
fz_device_container_stack_is_tile,
|
||||
};
|
||||
|
||||
/* Structure types */
|
||||
typedef enum
|
||||
{
|
||||
FZ_STRUCTURE_INVALID = -1,
|
||||
|
||||
/* Grouping elements (PDF 1.7 - Table 10.20) */
|
||||
FZ_STRUCTURE_DOCUMENT,
|
||||
FZ_STRUCTURE_PART,
|
||||
FZ_STRUCTURE_ART,
|
||||
FZ_STRUCTURE_SECT,
|
||||
FZ_STRUCTURE_DIV,
|
||||
FZ_STRUCTURE_BLOCKQUOTE,
|
||||
FZ_STRUCTURE_CAPTION,
|
||||
FZ_STRUCTURE_TOC,
|
||||
FZ_STRUCTURE_TOCI,
|
||||
FZ_STRUCTURE_INDEX,
|
||||
FZ_STRUCTURE_NONSTRUCT,
|
||||
FZ_STRUCTURE_PRIVATE,
|
||||
/* Grouping elements (PDF 2.0 - Table 364) */
|
||||
FZ_STRUCTURE_DOCUMENTFRAGMENT,
|
||||
/* Grouping elements (PDF 2.0 - Table 365) */
|
||||
FZ_STRUCTURE_ASIDE,
|
||||
/* Grouping elements (PDF 2.0 - Table 366) */
|
||||
FZ_STRUCTURE_TITLE,
|
||||
FZ_STRUCTURE_FENOTE,
|
||||
/* Grouping elements (PDF 2.0 - Table 367) */
|
||||
FZ_STRUCTURE_SUB,
|
||||
|
||||
/* Paragraphlike elements (PDF 1.7 - Table 10.21) */
|
||||
FZ_STRUCTURE_P,
|
||||
FZ_STRUCTURE_H,
|
||||
FZ_STRUCTURE_H1,
|
||||
FZ_STRUCTURE_H2,
|
||||
FZ_STRUCTURE_H3,
|
||||
FZ_STRUCTURE_H4,
|
||||
FZ_STRUCTURE_H5,
|
||||
FZ_STRUCTURE_H6,
|
||||
|
||||
/* List elements (PDF 1.7 - Table 10.23) */
|
||||
FZ_STRUCTURE_LIST,
|
||||
FZ_STRUCTURE_LISTITEM,
|
||||
FZ_STRUCTURE_LABEL,
|
||||
FZ_STRUCTURE_LISTBODY,
|
||||
|
||||
/* Table elements (PDF 1.7 - Table 10.24) */
|
||||
FZ_STRUCTURE_TABLE,
|
||||
FZ_STRUCTURE_TR,
|
||||
FZ_STRUCTURE_TH,
|
||||
FZ_STRUCTURE_TD,
|
||||
FZ_STRUCTURE_THEAD,
|
||||
FZ_STRUCTURE_TBODY,
|
||||
FZ_STRUCTURE_TFOOT,
|
||||
|
||||
/* Inline elements (PDF 1.7 - Table 10.25) */
|
||||
FZ_STRUCTURE_SPAN,
|
||||
FZ_STRUCTURE_QUOTE,
|
||||
FZ_STRUCTURE_NOTE,
|
||||
FZ_STRUCTURE_REFERENCE,
|
||||
FZ_STRUCTURE_BIBENTRY,
|
||||
FZ_STRUCTURE_CODE,
|
||||
FZ_STRUCTURE_LINK,
|
||||
FZ_STRUCTURE_ANNOT,
|
||||
/* Inline elements (PDF 2.0 - Table 368) */
|
||||
FZ_STRUCTURE_EM,
|
||||
FZ_STRUCTURE_STRONG,
|
||||
|
||||
/* Ruby inline element (PDF 1.7 - Table 10.26) */
|
||||
FZ_STRUCTURE_RUBY,
|
||||
FZ_STRUCTURE_RB,
|
||||
FZ_STRUCTURE_RT,
|
||||
FZ_STRUCTURE_RP,
|
||||
|
||||
/* Warichu inline element (PDF 1.7 - Table 10.26) */
|
||||
FZ_STRUCTURE_WARICHU,
|
||||
FZ_STRUCTURE_WT,
|
||||
FZ_STRUCTURE_WP,
|
||||
|
||||
/* Illustration elements (PDF 1.7 - Table 10.27) */
|
||||
FZ_STRUCTURE_FIGURE,
|
||||
FZ_STRUCTURE_FORMULA,
|
||||
FZ_STRUCTURE_FORM,
|
||||
|
||||
/* Artifact structure type (PDF 2.0 - Table 375) */
|
||||
FZ_STRUCTURE_ARTIFACT
|
||||
} fz_structure;
|
||||
|
||||
const char *fz_structure_to_string(fz_structure type);
|
||||
fz_structure fz_structure_from_string(const char *str);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FZ_METATEXT_ACTUALTEXT,
|
||||
FZ_METATEXT_ALT,
|
||||
FZ_METATEXT_ABBREVIATION,
|
||||
FZ_METATEXT_TITLE
|
||||
} fz_metatext;
|
||||
|
||||
struct fz_device
|
||||
{
|
||||
int refs;
|
||||
int hints;
|
||||
int flags;
|
||||
|
||||
void (*close_device)(fz_context *, fz_device *);
|
||||
void (*drop_device)(fz_context *, fz_device *);
|
||||
|
||||
void (*fill_path)(fz_context *, fz_device *, const fz_path *, int even_odd, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params );
|
||||
void (*stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params );
|
||||
void (*clip_path)(fz_context *, fz_device *, const fz_path *, int even_odd, fz_matrix, fz_rect scissor);
|
||||
void (*clip_stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, fz_matrix, fz_rect scissor);
|
||||
|
||||
void (*fill_text)(fz_context *, fz_device *, const fz_text *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params );
|
||||
void (*stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params );
|
||||
void (*clip_text)(fz_context *, fz_device *, const fz_text *, fz_matrix, fz_rect scissor);
|
||||
void (*clip_stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, fz_matrix, fz_rect scissor);
|
||||
void (*ignore_text)(fz_context *, fz_device *, const fz_text *, fz_matrix );
|
||||
|
||||
void (*fill_shade)(fz_context *, fz_device *, fz_shade *shd, fz_matrix ctm, float alpha, fz_color_params color_params);
|
||||
void (*fill_image)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, float alpha, fz_color_params color_params);
|
||||
void (*fill_image_mask)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, fz_colorspace *, const float *color, float alpha, fz_color_params color_params);
|
||||
void (*clip_image_mask)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, fz_rect scissor);
|
||||
|
||||
void (*pop_clip)(fz_context *, fz_device *);
|
||||
|
||||
void (*begin_mask)(fz_context *, fz_device *, fz_rect area, int luminosity, fz_colorspace *, const float *bc, fz_color_params );
|
||||
void (*end_mask)(fz_context *, fz_device *);
|
||||
void (*begin_group)(fz_context *, fz_device *, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha);
|
||||
void (*end_group)(fz_context *, fz_device *);
|
||||
|
||||
int (*begin_tile)(fz_context *, fz_device *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id);
|
||||
void (*end_tile)(fz_context *, fz_device *);
|
||||
|
||||
void (*render_flags)(fz_context *, fz_device *, int set, int clear);
|
||||
void (*set_default_colorspaces)(fz_context *, fz_device *, fz_default_colorspaces *);
|
||||
|
||||
void (*begin_layer)(fz_context *, fz_device *, const char *layer_name);
|
||||
void (*end_layer)(fz_context *, fz_device *);
|
||||
|
||||
void (*begin_structure)(fz_context *, fz_device *, fz_structure standard, const char *raw, int uid);
|
||||
void (*end_structure)(fz_context *, fz_device *);
|
||||
|
||||
void (*begin_metatext)(fz_context *, fz_device *, fz_metatext meta, const char *text);
|
||||
void (*end_metatext)(fz_context *, fz_device *);
|
||||
|
||||
fz_rect d1_rect;
|
||||
|
||||
int container_len;
|
||||
int container_cap;
|
||||
fz_device_container_stack *container;
|
||||
};
|
||||
|
||||
/**
|
||||
Device calls; graphics primitives and containers.
|
||||
*/
|
||||
void fz_fill_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
|
||||
void fz_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
|
||||
void fz_clip_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, fz_rect scissor);
|
||||
void fz_clip_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor);
|
||||
void fz_fill_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
|
||||
void fz_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
|
||||
void fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, fz_rect scissor);
|
||||
void fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor);
|
||||
void fz_ignore_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm);
|
||||
void fz_pop_clip(fz_context *ctx, fz_device *dev);
|
||||
void fz_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha, fz_color_params color_params);
|
||||
void fz_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, float alpha, fz_color_params color_params);
|
||||
void fz_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
|
||||
void fz_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_rect scissor);
|
||||
void fz_begin_mask(fz_context *ctx, fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, const float *bc, fz_color_params color_params);
|
||||
void fz_end_mask(fz_context *ctx, fz_device *dev);
|
||||
void fz_begin_group(fz_context *ctx, fz_device *dev, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha);
|
||||
void fz_end_group(fz_context *ctx, fz_device *dev);
|
||||
void fz_begin_tile(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm);
|
||||
int fz_begin_tile_id(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id);
|
||||
void fz_end_tile(fz_context *ctx, fz_device *dev);
|
||||
void fz_render_flags(fz_context *ctx, fz_device *dev, int set, int clear);
|
||||
void fz_set_default_colorspaces(fz_context *ctx, fz_device *dev, fz_default_colorspaces *default_cs);
|
||||
void fz_begin_layer(fz_context *ctx, fz_device *dev, const char *layer_name);
|
||||
void fz_end_layer(fz_context *ctx, fz_device *dev);
|
||||
void fz_begin_structure(fz_context *ctx, fz_device *dev, fz_structure standard, const char *raw, int uid);
|
||||
void fz_end_structure(fz_context *ctx, fz_device *dev);
|
||||
void fz_begin_metatext(fz_context *ctx, fz_device *dev, fz_metatext meta, const char *text);
|
||||
void fz_end_metatext(fz_context *ctx, fz_device *dev);
|
||||
|
||||
/**
|
||||
Devices are created by calls to device implementations, for
|
||||
instance: foo_new_device(). These will be implemented by calling
|
||||
fz_new_derived_device(ctx, foo_device) where foo_device is a
|
||||
structure "derived from" fz_device, for instance
|
||||
typedef struct { fz_device base; ...extras...} foo_device;
|
||||
*/
|
||||
fz_device *fz_new_device_of_size(fz_context *ctx, int size);
|
||||
#define fz_new_derived_device(CTX, TYPE) \
|
||||
((TYPE *)Memento_label(fz_new_device_of_size(ctx,sizeof(TYPE)),#TYPE))
|
||||
|
||||
/**
|
||||
Signal the end of input, and flush any buffered output.
|
||||
This is NOT called implicitly on fz_drop_device. This
|
||||
may throw exceptions.
|
||||
*/
|
||||
void fz_close_device(fz_context *ctx, fz_device *dev);
|
||||
|
||||
/**
|
||||
Reduce the reference count on a device. When the reference count
|
||||
reaches zero, the device and its resources will be freed.
|
||||
Don't forget to call fz_close_device before dropping the device,
|
||||
or you may get incomplete output!
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_drop_device(fz_context *ctx, fz_device *dev);
|
||||
|
||||
/**
|
||||
Increment the reference count for a device. Returns the same
|
||||
pointer.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
fz_device *fz_keep_device(fz_context *ctx, fz_device *dev);
|
||||
|
||||
/**
|
||||
Enable (set) hint bits within the hint bitfield for a device.
|
||||
*/
|
||||
void fz_enable_device_hints(fz_context *ctx, fz_device *dev, int hints);
|
||||
|
||||
/**
|
||||
Disable (clear) hint bits within the hint bitfield for a device.
|
||||
*/
|
||||
void fz_disable_device_hints(fz_context *ctx, fz_device *dev, int hints);
|
||||
|
||||
/**
|
||||
Find current scissor region as tracked by the device.
|
||||
*/
|
||||
fz_rect fz_device_current_scissor(fz_context *ctx, fz_device *dev);
|
||||
|
||||
enum
|
||||
{
|
||||
/* Hints */
|
||||
FZ_DONT_INTERPOLATE_IMAGES = 1,
|
||||
FZ_NO_CACHE = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
Cookie support - simple communication channel between app/library.
|
||||
*/
|
||||
|
||||
/**
|
||||
Provide two-way communication between application and library.
|
||||
Intended for multi-threaded applications where one thread is
|
||||
rendering pages and another thread wants to read progress
|
||||
feedback or abort a job that takes a long time to finish. The
|
||||
communication is unsynchronized without locking.
|
||||
|
||||
abort: The application should set this field to 0 before
|
||||
calling fz_run_page to render a page. At any point when the
|
||||
page is being rendered the application my set this field to 1
|
||||
which will cause the rendering to finish soon. This field is
|
||||
checked periodically when the page is rendered, but exactly
|
||||
when is not known, therefore there is no upper bound on
|
||||
exactly when the rendering will abort. If the application
|
||||
did not provide a set of locks to fz_new_context, it must also
|
||||
await the completion of fz_run_page before issuing another
|
||||
call to fz_run_page. Note that once the application has set
|
||||
this field to 1 after it called fz_run_page it may not change
|
||||
the value again.
|
||||
|
||||
progress: Communicates rendering progress back to the
|
||||
application and is read only. Increments as a page is being
|
||||
rendered. The value starts out at 0 and is limited to less
|
||||
than or equal to progress_max, unless progress_max is -1.
|
||||
|
||||
progress_max: Communicates the known upper bound of rendering
|
||||
back to the application and is read only. The maximum value
|
||||
that the progress field may take. If there is no known upper
|
||||
bound on how long the rendering may take this value is -1 and
|
||||
progress is not limited. Note that the value of progress_max
|
||||
may change from -1 to a positive value once an upper bound is
|
||||
known, so take this into consideration when comparing the
|
||||
value of progress to that of progress_max.
|
||||
|
||||
errors: count of errors during current rendering.
|
||||
|
||||
incomplete: Initially should be set to 0. Will be set to
|
||||
non-zero if a TRYLATER error is thrown during rendering.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int abort;
|
||||
int progress;
|
||||
size_t progress_max; /* (size_t)-1 for unknown */
|
||||
int errors;
|
||||
int incomplete;
|
||||
} fz_cookie;
|
||||
|
||||
/**
|
||||
Create a device to print a debug trace of all device calls.
|
||||
*/
|
||||
fz_device *fz_new_trace_device(fz_context *ctx, fz_output *out);
|
||||
|
||||
/**
|
||||
Create a device to output raw information.
|
||||
*/
|
||||
fz_device *fz_new_xmltext_device(fz_context *ctx, fz_output *out);
|
||||
|
||||
/**
|
||||
Create a device to compute the bounding
|
||||
box of all marks on a page.
|
||||
|
||||
The returned bounding box will be the union of all bounding
|
||||
boxes of all objects on a page.
|
||||
*/
|
||||
fz_device *fz_new_bbox_device(fz_context *ctx, fz_rect *rectp);
|
||||
|
||||
/**
|
||||
Create a device to test for features.
|
||||
|
||||
Currently only tests for the presence of non-grayscale colors.
|
||||
|
||||
is_color: Possible values returned:
|
||||
0: Definitely greyscale
|
||||
1: Probably color (all colors were grey, but there
|
||||
were images or shadings in a non grey colorspace).
|
||||
2: Definitely color
|
||||
|
||||
threshold: The difference from grayscale that will be tolerated.
|
||||
Typical values to use are either 0 (be exact) and 0.02 (allow an
|
||||
imperceptible amount of slop).
|
||||
|
||||
options: A set of bitfield options, from the FZ_TEST_OPT set.
|
||||
|
||||
passthrough: A device to pass all calls through to, or NULL.
|
||||
If set, then the test device can both test and pass through to
|
||||
an underlying device (like, say, the display list device). This
|
||||
means that a display list can be created and at the end we'll
|
||||
know if it's colored or not.
|
||||
|
||||
In the absence of a passthrough device, the device will throw
|
||||
an exception to stop page interpretation when color is found.
|
||||
*/
|
||||
fz_device *fz_new_test_device(fz_context *ctx, int *is_color, float threshold, int options, fz_device *passthrough);
|
||||
|
||||
enum
|
||||
{
|
||||
/* If set, test every pixel of images exhaustively.
|
||||
* If clear, just look at colorspaces for images. */
|
||||
FZ_TEST_OPT_IMAGES = 1,
|
||||
|
||||
/* If set, test every pixel of shadings. */
|
||||
/* If clear, just look at colorspaces for shadings. */
|
||||
FZ_TEST_OPT_SHADINGS = 2
|
||||
};
|
||||
|
||||
/**
|
||||
Create a device to draw on a pixmap.
|
||||
|
||||
dest: Target pixmap for the draw device. See fz_new_pixmap*
|
||||
for how to obtain a pixmap. The pixmap is not cleared by the
|
||||
draw device, see fz_clear_pixmap* for how to clear it prior to
|
||||
calling fz_new_draw_device. Free the device by calling
|
||||
fz_drop_device.
|
||||
|
||||
transform: Transform from user space in points to device space
|
||||
in pixels.
|
||||
*/
|
||||
fz_device *fz_new_draw_device(fz_context *ctx, fz_matrix transform, fz_pixmap *dest);
|
||||
|
||||
/**
|
||||
Create a device to draw on a pixmap.
|
||||
|
||||
dest: Target pixmap for the draw device. See fz_new_pixmap*
|
||||
for how to obtain a pixmap. The pixmap is not cleared by the
|
||||
draw device, see fz_clear_pixmap* for how to clear it prior to
|
||||
calling fz_new_draw_device. Free the device by calling
|
||||
fz_drop_device.
|
||||
|
||||
transform: Transform from user space in points to device space
|
||||
in pixels.
|
||||
|
||||
clip: Bounding box to restrict any marking operations of the
|
||||
draw device.
|
||||
*/
|
||||
fz_device *fz_new_draw_device_with_bbox(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, const fz_irect *clip);
|
||||
|
||||
/**
|
||||
Create a device to draw on a pixmap.
|
||||
|
||||
dest: Target pixmap for the draw device. See fz_new_pixmap*
|
||||
for how to obtain a pixmap. The pixmap is not cleared by the
|
||||
draw device, see fz_clear_pixmap* for how to clear it prior to
|
||||
calling fz_new_draw_device. Free the device by calling
|
||||
fz_drop_device.
|
||||
|
||||
transform: Transform from user space in points to device space
|
||||
in pixels.
|
||||
|
||||
proof_cs: Intermediate color space to map though when mapping to
|
||||
color space defined by pixmap.
|
||||
*/
|
||||
fz_device *fz_new_draw_device_with_proof(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, fz_colorspace *proof_cs);
|
||||
|
||||
/**
|
||||
Create a device to draw on a pixmap.
|
||||
|
||||
dest: Target pixmap for the draw device. See fz_new_pixmap*
|
||||
for how to obtain a pixmap. The pixmap is not cleared by the
|
||||
draw device, see fz_clear_pixmap* for how to clear it prior to
|
||||
calling fz_new_draw_device. Free the device by calling
|
||||
fz_drop_device.
|
||||
|
||||
transform: Transform from user space in points to device space
|
||||
in pixels.
|
||||
|
||||
clip: Bounding box to restrict any marking operations of the
|
||||
draw device.
|
||||
|
||||
proof_cs: Color space to render to prior to mapping to color
|
||||
space defined by pixmap.
|
||||
*/
|
||||
fz_device *fz_new_draw_device_with_bbox_proof(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, const fz_irect *clip, fz_colorspace *cs);
|
||||
|
||||
fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_matrix transform, fz_pixmap *dest);
|
||||
|
||||
/**
|
||||
struct fz_draw_options: Options for creating a pixmap and draw
|
||||
device.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int rotate;
|
||||
int x_resolution;
|
||||
int y_resolution;
|
||||
int width;
|
||||
int height;
|
||||
fz_colorspace *colorspace;
|
||||
int alpha;
|
||||
int graphics;
|
||||
int text;
|
||||
} fz_draw_options;
|
||||
|
||||
FZ_DATA extern const char *fz_draw_options_usage;
|
||||
|
||||
/**
|
||||
Parse draw device options from a comma separated key-value string.
|
||||
*/
|
||||
fz_draw_options *fz_parse_draw_options(fz_context *ctx, fz_draw_options *options, const char *string);
|
||||
|
||||
/**
|
||||
Create a new pixmap and draw device, using the specified options.
|
||||
|
||||
options: Options to configure the draw device, and choose the
|
||||
resolution and colorspace.
|
||||
|
||||
mediabox: The bounds of the page in points.
|
||||
|
||||
pixmap: An out parameter containing the newly created pixmap.
|
||||
*/
|
||||
fz_device *fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *options, fz_rect mediabox, fz_pixmap **pixmap);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_DISPLAY_LIST_H
|
||||
#define MUPDF_FITZ_DISPLAY_LIST_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/geometry.h"
|
||||
#include "mupdf/fitz/device.h"
|
||||
|
||||
/**
|
||||
Display list device -- record and play back device commands.
|
||||
*/
|
||||
|
||||
/**
|
||||
fz_display_list is a list containing drawing commands (text,
|
||||
images, etc.). The intent is two-fold: as a caching-mechanism
|
||||
to reduce parsing of a page, and to be used as a data
|
||||
structure in multi-threading where one thread parses the page
|
||||
and another renders pages.
|
||||
|
||||
Create a display list with fz_new_display_list, hand it over to
|
||||
fz_new_list_device to have it populated, and later replay the
|
||||
list (once or many times) by calling fz_run_display_list. When
|
||||
the list is no longer needed drop it with fz_drop_display_list.
|
||||
*/
|
||||
typedef struct fz_display_list fz_display_list;
|
||||
|
||||
/**
|
||||
Create an empty display list.
|
||||
|
||||
A display list contains drawing commands (text, images, etc.).
|
||||
Use fz_new_list_device for populating the list.
|
||||
|
||||
mediabox: Bounds of the page (in points) represented by the
|
||||
display list.
|
||||
*/
|
||||
fz_display_list *fz_new_display_list(fz_context *ctx, fz_rect mediabox);
|
||||
|
||||
/**
|
||||
Create a rendering device for a display list.
|
||||
|
||||
When the device is rendering a page it will populate the
|
||||
display list with drawing commands (text, images, etc.). The
|
||||
display list can later be reused to render a page many times
|
||||
without having to re-interpret the page from the document file
|
||||
for each rendering. Once the device is no longer needed, free
|
||||
it with fz_drop_device.
|
||||
|
||||
list: A display list that the list device takes a reference to.
|
||||
*/
|
||||
fz_device *fz_new_list_device(fz_context *ctx, fz_display_list *list);
|
||||
|
||||
/**
|
||||
(Re)-run a display list through a device.
|
||||
|
||||
list: A display list, created by fz_new_display_list and
|
||||
populated with objects from a page by running fz_run_page on a
|
||||
device obtained from fz_new_list_device.
|
||||
|
||||
ctm: Transform to apply to display list contents. May include
|
||||
for example scaling and rotation, see fz_scale, fz_rotate and
|
||||
fz_concat. Set to fz_identity if no transformation is desired.
|
||||
|
||||
scissor: Only the part of the contents of the display list
|
||||
visible within this area will be considered when the list is
|
||||
run through the device. This does not imply for tile objects
|
||||
contained in the display list.
|
||||
|
||||
cookie: Communication mechanism between caller and library
|
||||
running the page. Intended for multi-threaded applications,
|
||||
while single-threaded applications set cookie to NULL. The
|
||||
caller may abort an ongoing page run. Cookie also communicates
|
||||
progress information back to the caller. The fields inside
|
||||
cookie are continually updated while the page is being run.
|
||||
*/
|
||||
void fz_run_display_list(fz_context *ctx, fz_display_list *list, fz_device *dev, fz_matrix ctm, fz_rect scissor, fz_cookie *cookie);
|
||||
|
||||
/**
|
||||
Increment the reference count for a display list. Returns the
|
||||
same pointer.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
fz_display_list *fz_keep_display_list(fz_context *ctx, fz_display_list *list);
|
||||
|
||||
/**
|
||||
Decrement the reference count for a display list. When the
|
||||
reference count reaches zero, all the references in the display
|
||||
list itself are dropped, and the display list is freed.
|
||||
|
||||
Never throws exceptions.
|
||||
*/
|
||||
void fz_drop_display_list(fz_context *ctx, fz_display_list *list);
|
||||
|
||||
/**
|
||||
Return the bounding box of the page recorded in a display list.
|
||||
*/
|
||||
fz_rect fz_bound_display_list(fz_context *ctx, fz_display_list *list);
|
||||
|
||||
/**
|
||||
Create a new image from a display list.
|
||||
|
||||
w, h: The conceptual width/height of the image.
|
||||
|
||||
transform: The matrix that needs to be applied to the given
|
||||
list to make it render to the unit square.
|
||||
|
||||
list: The display list.
|
||||
*/
|
||||
fz_image *fz_new_image_from_display_list(fz_context *ctx, float w, float h, fz_display_list *list);
|
||||
|
||||
/**
|
||||
Check for a display list being empty
|
||||
|
||||
list: The list to check.
|
||||
|
||||
Returns true if empty, false otherwise.
|
||||
*/
|
||||
int fz_display_list_is_empty(fz_context *ctx, const fz_display_list *list);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,52 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_EXPORT_H
|
||||
#define MUPDF_FITZ_EXPORT_H
|
||||
|
||||
/*
|
||||
* Support for building/using MuPDF DLL on Windows.
|
||||
*
|
||||
* When compiling code that uses MuPDF DLL, FZ_DLL_CLIENT should be defined.
|
||||
*
|
||||
* When compiling MuPDF DLL itself, FZ_DLL should be defined.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#if defined(FZ_DLL)
|
||||
/* Building DLL. */
|
||||
#define FZ_FUNCTION __declspec(dllexport)
|
||||
#define FZ_DATA __declspec(dllexport)
|
||||
#elif defined(FZ_DLL_CLIENT)
|
||||
/* Building DLL client code. */
|
||||
#define FZ_FUNCTION __declspec(dllexport)
|
||||
#define FZ_DATA __declspec(dllimport)
|
||||
#else
|
||||
#define FZ_FUNCTION
|
||||
#define FZ_DATA
|
||||
#endif
|
||||
#else
|
||||
#define FZ_FUNCTION
|
||||
#define FZ_DATA
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,251 @@
|
||||
// Copyright (C) 2004-2023 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_FILTER_H
|
||||
#define MUPDF_FITZ_FILTER_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/buffer.h"
|
||||
#include "mupdf/fitz/store.h"
|
||||
#include "mupdf/fitz/stream.h"
|
||||
|
||||
typedef struct fz_jbig2_globals fz_jbig2_globals;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int64_t offset;
|
||||
uint64_t length;
|
||||
} fz_range;
|
||||
|
||||
/**
|
||||
The null filter reads a specified amount of data from the
|
||||
substream.
|
||||
*/
|
||||
fz_stream *fz_open_null_filter(fz_context *ctx, fz_stream *chain, uint64_t len, int64_t offset);
|
||||
|
||||
/**
|
||||
The range filter copies data from specified ranges of the
|
||||
chained stream.
|
||||
*/
|
||||
fz_stream *fz_open_range_filter(fz_context *ctx, fz_stream *chain, fz_range *ranges, int nranges);
|
||||
|
||||
/**
|
||||
The endstream filter reads a PDF substream, and starts to look
|
||||
for an 'endstream' token after the specified length.
|
||||
*/
|
||||
fz_stream *fz_open_endstream_filter(fz_context *ctx, fz_stream *chain, uint64_t len, int64_t offset);
|
||||
|
||||
/**
|
||||
Concat filter concatenates several streams into one.
|
||||
*/
|
||||
fz_stream *fz_open_concat(fz_context *ctx, int max, int pad);
|
||||
|
||||
/**
|
||||
Add a chained stream to the end of the concatenate filter.
|
||||
|
||||
Ownership of chain is passed in.
|
||||
*/
|
||||
void fz_concat_push_drop(fz_context *ctx, fz_stream *concat, fz_stream *chain);
|
||||
|
||||
/**
|
||||
arc4 filter performs RC4 decoding of data read from the chained
|
||||
filter using the supplied key.
|
||||
*/
|
||||
fz_stream *fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
|
||||
|
||||
/**
|
||||
aesd filter performs AES decoding of data read from the chained
|
||||
filter using the supplied key.
|
||||
*/
|
||||
fz_stream *fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
|
||||
|
||||
/**
|
||||
a85d filter performs ASCII 85 Decoding of data read
|
||||
from the chained filter.
|
||||
*/
|
||||
fz_stream *fz_open_a85d(fz_context *ctx, fz_stream *chain);
|
||||
|
||||
/**
|
||||
ahxd filter performs ASCII Hex decoding of data read
|
||||
from the chained filter.
|
||||
*/
|
||||
fz_stream *fz_open_ahxd(fz_context *ctx, fz_stream *chain);
|
||||
|
||||
/**
|
||||
rld filter performs Run Length Decoding of data read
|
||||
from the chained filter.
|
||||
*/
|
||||
fz_stream *fz_open_rld(fz_context *ctx, fz_stream *chain);
|
||||
|
||||
/**
|
||||
dctd filter performs DCT (JPEG) decoding of data read
|
||||
from the chained filter.
|
||||
|
||||
color_transform implements the PDF color_transform option;
|
||||
use 0 to disable YUV-RGB / YCCK-CMYK transforms
|
||||
use >0 to enable YUV-RGB / YCCK-CMYK transforms
|
||||
use -1 (default) if not embedded in PDF
|
||||
use -2 (default) if embedded in PDF
|
||||
|
||||
For subsampling on decode, set l2factor to the log2 of the
|
||||
reduction required (therefore 0 = full size decode).
|
||||
|
||||
jpegtables is an optional stream from which the JPEG tables
|
||||
can be read. Use NULL if not required.
|
||||
*/
|
||||
fz_stream *fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int l2factor, fz_stream *jpegtables);
|
||||
|
||||
/**
|
||||
faxd filter performs FAX decoding of data read from
|
||||
the chained filter.
|
||||
|
||||
k: see fax specification (fax default is 0).
|
||||
|
||||
end_of_line: whether we expect end of line markers (fax default
|
||||
is 0).
|
||||
|
||||
encoded_byte_align: whether we align to bytes after each line
|
||||
(fax default is 0).
|
||||
|
||||
columns: how many columns in the image (fax default is 1728).
|
||||
|
||||
rows: 0 for unspecified or the number of rows of data to expect.
|
||||
|
||||
end_of_block: whether we expect end of block markers (fax
|
||||
default is 1).
|
||||
|
||||
black_is_1: determines the polarity of the image (fax default is
|
||||
0).
|
||||
*/
|
||||
fz_stream *fz_open_faxd(fz_context *ctx, fz_stream *chain,
|
||||
int k, int end_of_line, int encoded_byte_align,
|
||||
int columns, int rows, int end_of_block, int black_is_1);
|
||||
|
||||
/**
|
||||
flated filter performs LZ77 decoding (inflating) of data read
|
||||
from the chained filter.
|
||||
|
||||
window_bits: How large a decompression window to use. Typically
|
||||
15. A negative number, -n, means to use n bits, but to expect
|
||||
raw data with no header.
|
||||
*/
|
||||
fz_stream *fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits);
|
||||
|
||||
/**
|
||||
lzwd filter performs LZW decoding of data read from the chained
|
||||
filter.
|
||||
|
||||
early_change: (Default 1) specifies whether to change codes 1
|
||||
bit early.
|
||||
|
||||
min_bits: (Default 9) specifies the minimum number of bits to
|
||||
use.
|
||||
|
||||
reverse_bits: (Default 0) allows for compatibility with gif and
|
||||
old style tiffs (1).
|
||||
|
||||
old_tiff: (Default 0) allows for different handling of the clear
|
||||
code, as found in old style tiffs.
|
||||
*/
|
||||
fz_stream *fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits, int reverse_bits, int old_tiff);
|
||||
|
||||
/**
|
||||
predict filter performs pixel prediction on data read from
|
||||
the chained filter.
|
||||
|
||||
predictor: 1 = copy, 2 = tiff, other = inline PNG predictor
|
||||
|
||||
columns: width of image in pixels
|
||||
|
||||
colors: number of components.
|
||||
|
||||
bpc: bits per component (typically 8)
|
||||
*/
|
||||
fz_stream *fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, int colors, int bpc);
|
||||
|
||||
/**
|
||||
Open a filter that performs jbig2 decompression on the chained
|
||||
stream, using the optional globals record.
|
||||
*/
|
||||
fz_stream *fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals, int embedded);
|
||||
|
||||
/**
|
||||
Create a jbig2 globals record from a buffer.
|
||||
|
||||
Immutable once created.
|
||||
*/
|
||||
fz_jbig2_globals *fz_load_jbig2_globals(fz_context *ctx, fz_buffer *buf);
|
||||
|
||||
/**
|
||||
Increment the reference count for a jbig2 globals record.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
fz_jbig2_globals *fz_keep_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals);
|
||||
|
||||
/**
|
||||
Decrement the reference count for a jbig2 globals record.
|
||||
When the reference count hits zero, the record is freed.
|
||||
|
||||
Never throws an exception.
|
||||
*/
|
||||
void fz_drop_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals);
|
||||
|
||||
/**
|
||||
Special jbig2 globals drop function for use in implementing
|
||||
store support.
|
||||
*/
|
||||
void fz_drop_jbig2_globals_imp(fz_context *ctx, fz_storable *globals);
|
||||
|
||||
/**
|
||||
Return buffer containing jbig2 globals data stream.
|
||||
*/
|
||||
fz_buffer * fz_jbig2_globals_data(fz_context *ctx, fz_jbig2_globals *globals);
|
||||
|
||||
/* Extra filters for tiff */
|
||||
|
||||
/**
|
||||
SGI Log 16bit (greyscale) decode from the chained filter.
|
||||
Decodes lines of w pixels to 8bpp greyscale.
|
||||
*/
|
||||
fz_stream *fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w);
|
||||
|
||||
/**
|
||||
SGI Log 24bit (LUV) decode from the chained filter.
|
||||
Decodes lines of w pixels to 8bpc rgb.
|
||||
*/
|
||||
fz_stream *fz_open_sgilog24(fz_context *ctx, fz_stream *chain, int w);
|
||||
|
||||
/**
|
||||
SGI Log 32bit (LUV) decode from the chained filter.
|
||||
Decodes lines of w pixels to 8bpc rgb.
|
||||
*/
|
||||
fz_stream *fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w);
|
||||
|
||||
/**
|
||||
4bit greyscale Thunderscan decoding from the chained filter.
|
||||
Decodes lines of w pixels to 8bpp greyscale.
|
||||
*/
|
||||
fz_stream *fz_open_thunder(fz_context *ctx, fz_stream *chain, int w);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,745 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_FONT_H
|
||||
#define MUPDF_FITZ_FONT_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/geometry.h"
|
||||
#include "mupdf/fitz/buffer.h"
|
||||
#include "mupdf/fitz/color.h"
|
||||
|
||||
/* forward declaration for circular dependency */
|
||||
struct fz_device;
|
||||
|
||||
/* Various font encoding tables and lookup functions */
|
||||
|
||||
FZ_DATA extern const char *fz_glyph_name_from_adobe_standard[256];
|
||||
FZ_DATA extern const char *fz_glyph_name_from_iso8859_7[256];
|
||||
FZ_DATA extern const char *fz_glyph_name_from_koi8u[256];
|
||||
FZ_DATA extern const char *fz_glyph_name_from_mac_expert[256];
|
||||
FZ_DATA extern const char *fz_glyph_name_from_mac_roman[256];
|
||||
FZ_DATA extern const char *fz_glyph_name_from_win_ansi[256];
|
||||
FZ_DATA extern const char *fz_glyph_name_from_windows_1252[256];
|
||||
|
||||
FZ_DATA extern const unsigned short fz_unicode_from_iso8859_1[256];
|
||||
FZ_DATA extern const unsigned short fz_unicode_from_iso8859_7[256];
|
||||
FZ_DATA extern const unsigned short fz_unicode_from_koi8u[256];
|
||||
FZ_DATA extern const unsigned short fz_unicode_from_pdf_doc_encoding[256];
|
||||
FZ_DATA extern const unsigned short fz_unicode_from_windows_1250[256];
|
||||
FZ_DATA extern const unsigned short fz_unicode_from_windows_1251[256];
|
||||
FZ_DATA extern const unsigned short fz_unicode_from_windows_1252[256];
|
||||
|
||||
int fz_iso8859_1_from_unicode(int u);
|
||||
int fz_iso8859_7_from_unicode(int u);
|
||||
int fz_koi8u_from_unicode(int u);
|
||||
int fz_windows_1250_from_unicode(int u);
|
||||
int fz_windows_1251_from_unicode(int u);
|
||||
int fz_windows_1252_from_unicode(int u);
|
||||
|
||||
int fz_unicode_from_glyph_name(const char *name);
|
||||
int fz_unicode_from_glyph_name_strict(const char *name);
|
||||
const char **fz_duplicate_glyph_names_from_unicode(int unicode);
|
||||
const char *fz_glyph_name_from_unicode_sc(int unicode);
|
||||
|
||||
/**
|
||||
An abstract font handle.
|
||||
*/
|
||||
typedef struct fz_font fz_font;
|
||||
|
||||
/**
|
||||
Fonts come in two variants:
|
||||
Regular fonts are handled by FreeType.
|
||||
Type 3 fonts have callbacks to the interpreter.
|
||||
*/
|
||||
|
||||
/**
|
||||
Retrieve the FT_Face handle
|
||||
for the font.
|
||||
|
||||
font: The font to query
|
||||
|
||||
Returns the FT_Face handle for the font, or NULL
|
||||
if not a freetype handled font. (Cast to void *
|
||||
to avoid nasty header exposure).
|
||||
*/
|
||||
void *fz_font_ft_face(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Retrieve the Type3 procs
|
||||
for a font.
|
||||
|
||||
font: The font to query
|
||||
|
||||
Returns the t3_procs pointer. Will be NULL for a
|
||||
non type-3 font.
|
||||
*/
|
||||
fz_buffer **fz_font_t3_procs(fz_context *ctx, fz_font *font);
|
||||
|
||||
/* common CJK font collections */
|
||||
enum { FZ_ADOBE_CNS, FZ_ADOBE_GB, FZ_ADOBE_JAPAN, FZ_ADOBE_KOREA };
|
||||
|
||||
/**
|
||||
Every fz_font carries a set of flags
|
||||
within it, in a fz_font_flags_t structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int is_mono : 1;
|
||||
unsigned int is_serif : 1;
|
||||
unsigned int is_bold : 1;
|
||||
unsigned int is_italic : 1;
|
||||
unsigned int ft_substitute : 1; /* use substitute metrics */
|
||||
unsigned int ft_stretch : 1; /* stretch to match PDF metrics */
|
||||
|
||||
unsigned int fake_bold : 1; /* synthesize bold */
|
||||
unsigned int fake_italic : 1; /* synthesize italic */
|
||||
unsigned int has_opentype : 1; /* has opentype shaping tables */
|
||||
unsigned int invalid_bbox : 1;
|
||||
|
||||
unsigned int cjk : 1;
|
||||
unsigned int cjk_lang : 2; /* CNS, GB, JAPAN, or KOREA */
|
||||
|
||||
unsigned int embed : 1;
|
||||
unsigned int never_embed : 1;
|
||||
} fz_font_flags_t;
|
||||
|
||||
/**
|
||||
Retrieve a pointer to the font flags
|
||||
for a given font. These can then be updated as required.
|
||||
|
||||
font: The font to query
|
||||
|
||||
Returns a pointer to the flags structure (or NULL, if
|
||||
the font is NULL).
|
||||
*/
|
||||
fz_font_flags_t *fz_font_flags(fz_font *font);
|
||||
|
||||
/**
|
||||
In order to shape a given font, we need to
|
||||
declare it to a shaper library (harfbuzz, by default, but others
|
||||
are possible). To avoid redeclaring it every time we need to
|
||||
shape, we hold a shaper handle and the destructor for it within
|
||||
the font itself. The handle is initialised by the caller when
|
||||
first required and the destructor is called when the fz_font is
|
||||
destroyed.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void *shaper_handle;
|
||||
void (*destroy)(fz_context *ctx, void *); /* Destructor for shape_handle */
|
||||
} fz_shaper_data_t;
|
||||
|
||||
/**
|
||||
Retrieve a pointer to the shaper data
|
||||
structure for the given font.
|
||||
|
||||
font: The font to query.
|
||||
|
||||
Returns a pointer to the shaper data structure (or NULL if
|
||||
font is NULL).
|
||||
*/
|
||||
fz_shaper_data_t *fz_font_shaper_data(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Retrieve a pointer to the name of the font.
|
||||
|
||||
font: The font to query.
|
||||
|
||||
Returns a pointer to an internal copy of the font name.
|
||||
Will never be NULL, but may be the empty string.
|
||||
*/
|
||||
const char *fz_font_name(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Query whether the font flags say that this font is bold.
|
||||
*/
|
||||
int fz_font_is_bold(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Query whether the font flags say that this font is italic.
|
||||
*/
|
||||
int fz_font_is_italic(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Query whether the font flags say that this font is serif.
|
||||
*/
|
||||
int fz_font_is_serif(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Query whether the font flags say that this font is monospaced.
|
||||
*/
|
||||
int fz_font_is_monospaced(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Retrieve the font bbox.
|
||||
|
||||
font: The font to query.
|
||||
|
||||
Returns the font bbox by value; it is valid only if
|
||||
fz_font_flags(font)->invalid_bbox is zero.
|
||||
*/
|
||||
fz_rect fz_font_bbox(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Type for user supplied system font loading hook.
|
||||
|
||||
name: The name of the font to load.
|
||||
|
||||
bold: 1 if a bold font desired, 0 otherwise.
|
||||
|
||||
italic: 1 if an italic font desired, 0 otherwise.
|
||||
needs_exact_metrics: 1 if an exact metric match is required for
|
||||
the font requested.
|
||||
|
||||
Returns a new font handle, or NULL if no font found (or on error).
|
||||
*/
|
||||
typedef fz_font *(fz_load_system_font_fn)(fz_context *ctx, const char *name, int bold, int italic, int needs_exact_metrics);
|
||||
|
||||
/**
|
||||
Type for user supplied cjk font loading hook.
|
||||
|
||||
name: The name of the font to load.
|
||||
|
||||
ordering: The ordering for which to load the font (e.g.
|
||||
FZ_ADOBE_KOREA)
|
||||
|
||||
serif: 1 if a serif font is desired, 0 otherwise.
|
||||
|
||||
Returns a new font handle, or NULL if no font found (or on error).
|
||||
*/
|
||||
typedef fz_font *(fz_load_system_cjk_font_fn)(fz_context *ctx, const char *name, int ordering, int serif);
|
||||
|
||||
/**
|
||||
Type for user supplied fallback font loading hook.
|
||||
|
||||
name: The name of the font to load.
|
||||
|
||||
script: UCDN script enum.
|
||||
|
||||
language: FZ_LANG enum.
|
||||
|
||||
serif, bold, italic: boolean style flags.
|
||||
|
||||
Returns a new font handle, or NULL if no font found (or on error).
|
||||
*/
|
||||
typedef fz_font *(fz_load_system_fallback_font_fn)(fz_context *ctx, int script, int language, int serif, int bold, int italic);
|
||||
|
||||
/**
|
||||
Install functions to allow MuPDF to request fonts from the
|
||||
system.
|
||||
|
||||
Only one set of hooks can be in use at a time.
|
||||
*/
|
||||
void fz_install_load_system_font_funcs(fz_context *ctx,
|
||||
fz_load_system_font_fn *f,
|
||||
fz_load_system_cjk_font_fn *f_cjk,
|
||||
fz_load_system_fallback_font_fn *f_fallback);
|
||||
|
||||
/**
|
||||
Attempt to load a given font from the system.
|
||||
|
||||
name: The name of the desired font.
|
||||
|
||||
bold: 1 if bold desired, 0 otherwise.
|
||||
|
||||
italic: 1 if italic desired, 0 otherwise.
|
||||
|
||||
needs_exact_metrics: 1 if an exact metrical match is required,
|
||||
0 otherwise.
|
||||
|
||||
Returns a new font handle, or NULL if no matching font was found
|
||||
(or on error).
|
||||
*/
|
||||
fz_font *fz_load_system_font(fz_context *ctx, const char *name, int bold, int italic, int needs_exact_metrics);
|
||||
|
||||
/**
|
||||
Attempt to load a given font from
|
||||
the system.
|
||||
|
||||
name: The name of the desired font.
|
||||
|
||||
ordering: The ordering to load the font from (e.g. FZ_ADOBE_KOREA)
|
||||
|
||||
serif: 1 if serif desired, 0 otherwise.
|
||||
|
||||
Returns a new font handle, or NULL if no matching font was found
|
||||
(or on error).
|
||||
*/
|
||||
fz_font *fz_load_system_cjk_font(fz_context *ctx, const char *name, int ordering, int serif);
|
||||
|
||||
/**
|
||||
Search the builtin fonts for a match.
|
||||
Whether a given font is present or not will depend on the
|
||||
configuration in which MuPDF is built.
|
||||
|
||||
name: The name of the font desired.
|
||||
|
||||
bold: 1 if bold desired, 0 otherwise.
|
||||
|
||||
italic: 1 if italic desired, 0 otherwise.
|
||||
|
||||
len: Pointer to a place to receive the length of the discovered
|
||||
font buffer.
|
||||
|
||||
Returns a pointer to the font file data, or NULL if not present.
|
||||
*/
|
||||
const unsigned char *fz_lookup_builtin_font(fz_context *ctx, const char *name, int bold, int italic, int *len);
|
||||
|
||||
/**
|
||||
Search the builtin base14 fonts for a match.
|
||||
Whether a given font is present or not will depend on the
|
||||
configuration in which MuPDF is built.
|
||||
|
||||
name: The name of the font desired.
|
||||
|
||||
len: Pointer to a place to receive the length of the discovered
|
||||
font buffer.
|
||||
|
||||
Returns a pointer to the font file data, or NULL if not present.
|
||||
*/
|
||||
const unsigned char *fz_lookup_base14_font(fz_context *ctx, const char *name, int *len);
|
||||
|
||||
/**
|
||||
Search the builtin cjk fonts for a match.
|
||||
Whether a font is present or not will depend on the
|
||||
configuration in which MuPDF is built.
|
||||
|
||||
ordering: The desired ordering of the font (e.g. FZ_ADOBE_KOREA).
|
||||
|
||||
len: Pointer to a place to receive the length of the discovered
|
||||
font buffer.
|
||||
|
||||
Returns a pointer to the font file data, or NULL if not present.
|
||||
*/
|
||||
const unsigned char *fz_lookup_cjk_font(fz_context *ctx, int ordering, int *len, int *index);
|
||||
|
||||
/**
|
||||
Search the builtin cjk fonts for a match for a given language.
|
||||
Whether a font is present or not will depend on the
|
||||
configuration in which MuPDF is built.
|
||||
|
||||
lang: Pointer to a (case sensitive) language string (e.g.
|
||||
"ja", "ko", "zh-Hant" etc).
|
||||
|
||||
len: Pointer to a place to receive the length of the discovered
|
||||
font buffer.
|
||||
|
||||
subfont: Pointer to a place to store the subfont index of the
|
||||
discovered font.
|
||||
|
||||
Returns a pointer to the font file data, or NULL if not present.
|
||||
*/
|
||||
const unsigned char *fz_lookup_cjk_font_by_language(fz_context *ctx, const char *lang, int *len, int *subfont);
|
||||
|
||||
/**
|
||||
Return the matching FZ_ADOBE_* ordering
|
||||
for the given language tag, such as "zh-Hant", "zh-Hans", "ja", or "ko".
|
||||
*/
|
||||
int fz_lookup_cjk_ordering_by_language(const char *name);
|
||||
|
||||
/**
|
||||
Search the builtin noto fonts for a match.
|
||||
Whether a font is present or not will depend on the
|
||||
configuration in which MuPDF is built.
|
||||
|
||||
script: The script desired (e.g. UCDN_SCRIPT_KATAKANA).
|
||||
|
||||
lang: The language desired (e.g. FZ_LANG_ja).
|
||||
|
||||
len: Pointer to a place to receive the length of the discovered
|
||||
font buffer.
|
||||
|
||||
Returns a pointer to the font file data, or NULL if not present.
|
||||
*/
|
||||
const unsigned char *fz_lookup_noto_font(fz_context *ctx, int script, int lang, int *len, int *subfont);
|
||||
|
||||
/**
|
||||
Search the builtin noto fonts specific symbol fonts.
|
||||
Whether a font is present or not will depend on the
|
||||
configuration in which MuPDF is built.
|
||||
*/
|
||||
const unsigned char *fz_lookup_noto_math_font(fz_context *ctx, int *len);
|
||||
const unsigned char *fz_lookup_noto_music_font(fz_context *ctx, int *len);
|
||||
const unsigned char *fz_lookup_noto_symbol1_font(fz_context *ctx, int *len);
|
||||
const unsigned char *fz_lookup_noto_symbol2_font(fz_context *ctx, int *len);
|
||||
const unsigned char *fz_lookup_noto_emoji_font(fz_context *ctx, int *len);
|
||||
|
||||
/**
|
||||
Try to load a fallback font for the
|
||||
given combination of font attributes. Whether a font is
|
||||
present or not will depend on the configuration in which
|
||||
MuPDF is built.
|
||||
|
||||
script: The script desired (e.g. UCDN_SCRIPT_KATAKANA).
|
||||
|
||||
language: The language desired (e.g. FZ_LANG_ja).
|
||||
|
||||
serif: 1 if serif desired, 0 otherwise.
|
||||
|
||||
bold: 1 if bold desired, 0 otherwise.
|
||||
|
||||
italic: 1 if italic desired, 0 otherwise.
|
||||
|
||||
Returns a new font handle, or NULL if not available.
|
||||
*/
|
||||
fz_font *fz_load_fallback_font(fz_context *ctx, int script, int language, int serif, int bold, int italic);
|
||||
|
||||
/**
|
||||
Create a new (empty) type3 font.
|
||||
|
||||
name: Name of font (or NULL).
|
||||
|
||||
matrix: Font matrix.
|
||||
|
||||
Returns a new font handle, or throws exception on
|
||||
allocation failure.
|
||||
*/
|
||||
fz_font *fz_new_type3_font(fz_context *ctx, const char *name, fz_matrix matrix);
|
||||
|
||||
/**
|
||||
Create a new font from a font file in memory.
|
||||
|
||||
Fonts created in this way, will be eligible for embedding by default.
|
||||
|
||||
name: Name of font (leave NULL to use name from font).
|
||||
|
||||
data: Pointer to the font file data.
|
||||
|
||||
len: Length of the font file data.
|
||||
|
||||
index: Which font from the file to load (0 for default).
|
||||
|
||||
use_glyph_box: 1 if we should use the glyph bbox, 0 otherwise.
|
||||
|
||||
Returns new font handle, or throws exception on error.
|
||||
*/
|
||||
fz_font *fz_new_font_from_memory(fz_context *ctx, const char *name, const unsigned char *data, int len, int index, int use_glyph_bbox);
|
||||
|
||||
/**
|
||||
Create a new font from a font file in a fz_buffer.
|
||||
|
||||
Fonts created in this way, will be eligible for embedding by default.
|
||||
|
||||
name: Name of font (leave NULL to use name from font).
|
||||
|
||||
buffer: Buffer to load from.
|
||||
|
||||
index: Which font from the file to load (0 for default).
|
||||
|
||||
use_glyph_box: 1 if we should use the glyph bbox, 0 otherwise.
|
||||
|
||||
Returns new font handle, or throws exception on error.
|
||||
*/
|
||||
fz_font *fz_new_font_from_buffer(fz_context *ctx, const char *name, fz_buffer *buffer, int index, int use_glyph_bbox);
|
||||
|
||||
/**
|
||||
Create a new font from a font file.
|
||||
|
||||
Fonts created in this way, will be eligible for embedding by default.
|
||||
|
||||
name: Name of font (leave NULL to use name from font).
|
||||
|
||||
path: File path to load from.
|
||||
|
||||
index: Which font from the file to load (0 for default).
|
||||
|
||||
use_glyph_box: 1 if we should use the glyph bbox, 0 otherwise.
|
||||
|
||||
Returns new font handle, or throws exception on error.
|
||||
*/
|
||||
fz_font *fz_new_font_from_file(fz_context *ctx, const char *name, const char *path, int index, int use_glyph_bbox);
|
||||
|
||||
/**
|
||||
Create a new font from one of the built-in fonts.
|
||||
*/
|
||||
fz_font *fz_new_base14_font(fz_context *ctx, const char *name);
|
||||
fz_font *fz_new_cjk_font(fz_context *ctx, int ordering);
|
||||
fz_font *fz_new_builtin_font(fz_context *ctx, const char *name, int is_bold, int is_italic);
|
||||
|
||||
/**
|
||||
Control whether a given font should be embedded or not when writing.
|
||||
*/
|
||||
void fz_set_font_embedding(fz_context *ctx, fz_font *font, int embed);
|
||||
|
||||
/**
|
||||
Add a reference to an existing fz_font.
|
||||
|
||||
font: The font to add a reference to.
|
||||
|
||||
Returns the same font.
|
||||
*/
|
||||
fz_font *fz_keep_font(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Drop a reference to a fz_font, destroying the
|
||||
font when the last reference is dropped.
|
||||
|
||||
font: The font to drop a reference to.
|
||||
*/
|
||||
void fz_drop_font(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Set the font bbox.
|
||||
|
||||
font: The font to set the bbox for.
|
||||
|
||||
xmin, ymin, xmax, ymax: The bounding box.
|
||||
*/
|
||||
void fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax);
|
||||
|
||||
/**
|
||||
Return a bbox for a given glyph in a font.
|
||||
|
||||
font: The font to look for the glyph in.
|
||||
|
||||
gid: The glyph to bound.
|
||||
|
||||
trm: The matrix to apply to the glyph before bounding.
|
||||
|
||||
Returns rectangle by value containing the bounds of the given
|
||||
glyph.
|
||||
*/
|
||||
fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm);
|
||||
|
||||
/**
|
||||
Determine if a given glyph in a font
|
||||
is cacheable. Certain glyphs in a type 3 font cannot safely
|
||||
be cached, as their appearance depends on the enclosing
|
||||
graphic state.
|
||||
|
||||
font: The font to look for the glyph in.
|
||||
|
||||
gif: The glyph to query.
|
||||
|
||||
Returns non-zero if cacheable, 0 if not.
|
||||
*/
|
||||
int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid);
|
||||
|
||||
/**
|
||||
Run a glyph from a Type3 font to
|
||||
a given device.
|
||||
|
||||
font: The font to find the glyph in.
|
||||
|
||||
gid: The glyph to run.
|
||||
|
||||
trm: The transform to apply.
|
||||
|
||||
dev: The device to render onto.
|
||||
*/
|
||||
void fz_run_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, struct fz_device *dev);
|
||||
|
||||
/**
|
||||
Return the advance for a given glyph.
|
||||
|
||||
font: The font to look for the glyph in.
|
||||
|
||||
glyph: The glyph to find the advance for.
|
||||
|
||||
wmode: 1 for vertical mode, 0 for horizontal.
|
||||
|
||||
Returns the advance for the glyph.
|
||||
*/
|
||||
float fz_advance_glyph(fz_context *ctx, fz_font *font, int glyph, int wmode);
|
||||
|
||||
/**
|
||||
Find the glyph id for a given unicode
|
||||
character within a font.
|
||||
|
||||
font: The font to look for the unicode character in.
|
||||
|
||||
unicode: The unicode character to encode.
|
||||
|
||||
Returns the glyph id for the given unicode value, or 0 if
|
||||
unknown.
|
||||
*/
|
||||
int fz_encode_character(fz_context *ctx, fz_font *font, int unicode);
|
||||
|
||||
/**
|
||||
Encode character, preferring small-caps variant if available.
|
||||
|
||||
font: The font to look for the unicode character in.
|
||||
|
||||
unicode: The unicode character to encode.
|
||||
|
||||
Returns the glyph id for the given unicode value, or 0 if
|
||||
unknown.
|
||||
*/
|
||||
int fz_encode_character_sc(fz_context *ctx, fz_font *font, int unicode);
|
||||
|
||||
/**
|
||||
Encode character.
|
||||
|
||||
Either by direct lookup of glyphname within a font, or, failing
|
||||
that, by mapping glyphname to unicode and thence to the glyph
|
||||
index within the given font.
|
||||
|
||||
Returns zero for type3 fonts.
|
||||
*/
|
||||
int fz_encode_character_by_glyph_name(fz_context *ctx, fz_font *font, const char *glyphname);
|
||||
|
||||
/**
|
||||
Find the glyph id for
|
||||
a given unicode character within a font, falling back to
|
||||
an alternative if not found.
|
||||
|
||||
font: The font to look for the unicode character in.
|
||||
|
||||
unicode: The unicode character to encode.
|
||||
|
||||
script: The script in use.
|
||||
|
||||
language: The language in use.
|
||||
|
||||
out_font: The font handle in which the given glyph represents
|
||||
the requested unicode character. The caller does not own the
|
||||
reference it is passed, so should call fz_keep_font if it is
|
||||
not simply to be used immediately.
|
||||
|
||||
Returns the glyph id for the given unicode value in the supplied
|
||||
font (and sets *out_font to font) if it is present. Otherwise
|
||||
an alternative fallback font (based on script/language) is
|
||||
searched for. If the glyph is found therein, *out_font is set
|
||||
to this reference, and the glyph reference is returned. If it
|
||||
cannot be found anywhere, the function returns 0.
|
||||
*/
|
||||
int fz_encode_character_with_fallback(fz_context *ctx, fz_font *font, int unicode, int script, int language, fz_font **out_font);
|
||||
|
||||
/**
|
||||
Find the name of a glyph
|
||||
|
||||
font: The font to look for the glyph in.
|
||||
|
||||
glyph: The glyph id to look for.
|
||||
|
||||
buf: Pointer to a buffer for the name to be inserted into.
|
||||
|
||||
size: The size of the buffer.
|
||||
|
||||
If a font contains a name table, then the name of the glyph
|
||||
will be returned in the supplied buffer. Otherwise a name
|
||||
is synthesised. The name will be truncated to fit in
|
||||
the buffer.
|
||||
*/
|
||||
void fz_get_glyph_name(fz_context *ctx, fz_font *font, int glyph, char *buf, int size);
|
||||
|
||||
/**
|
||||
Retrieve font ascender in ems.
|
||||
*/
|
||||
float fz_font_ascender(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Retrieve font descender in ems.
|
||||
*/
|
||||
float fz_font_descender(fz_context *ctx, fz_font *font);
|
||||
|
||||
/**
|
||||
Retrieve the MD5 digest for the font's data.
|
||||
*/
|
||||
void fz_font_digest(fz_context *ctx, fz_font *font, unsigned char digest[16]);
|
||||
|
||||
/* Implementation details: subject to change. */
|
||||
|
||||
void fz_decouple_type3_font(fz_context *ctx, fz_font *font, void *t3doc);
|
||||
|
||||
/**
|
||||
map an FT error number to a
|
||||
static string.
|
||||
|
||||
err: The error number to lookup.
|
||||
|
||||
Returns a pointer to a static textual representation
|
||||
of a freetype error.
|
||||
*/
|
||||
const char *ft_error_string(int err);
|
||||
int ft_char_index(void *face, int cid);
|
||||
int ft_name_index(void *face, const char *name);
|
||||
|
||||
/**
|
||||
Internal functions for our Harfbuzz integration
|
||||
to work around the lack of thread safety.
|
||||
*/
|
||||
|
||||
/**
|
||||
Lock against Harfbuzz being called
|
||||
simultaneously in several threads. This reuses
|
||||
FZ_LOCK_FREETYPE.
|
||||
*/
|
||||
void fz_hb_lock(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Unlock after a Harfbuzz call. This reuses
|
||||
FZ_LOCK_FREETYPE.
|
||||
*/
|
||||
void fz_hb_unlock(fz_context *ctx);
|
||||
|
||||
struct fz_font
|
||||
{
|
||||
int refs;
|
||||
char name[32];
|
||||
fz_buffer *buffer;
|
||||
|
||||
fz_font_flags_t flags;
|
||||
|
||||
void *ft_face; /* has an FT_Face if used */
|
||||
fz_shaper_data_t shaper_data;
|
||||
|
||||
fz_matrix t3matrix;
|
||||
void *t3resources;
|
||||
fz_buffer **t3procs; /* has 256 entries if used */
|
||||
struct fz_display_list **t3lists; /* has 256 entries if used */
|
||||
float *t3widths; /* has 256 entries if used */
|
||||
unsigned short *t3flags; /* has 256 entries if used */
|
||||
void *t3doc; /* a pdf_document for the callback */
|
||||
void (*t3run)(fz_context *ctx, void *doc, void *resources, fz_buffer *contents, struct fz_device *dev, fz_matrix ctm, void *gstate, fz_default_colorspaces *default_cs);
|
||||
void (*t3freeres)(fz_context *ctx, void *doc, void *resources);
|
||||
|
||||
fz_rect bbox; /* font bbox is used only for t3 fonts */
|
||||
|
||||
int glyph_count;
|
||||
|
||||
/* per glyph bounding box cache. */
|
||||
fz_rect **bbox_table;
|
||||
int use_glyph_bbox;
|
||||
|
||||
/* substitute metrics */
|
||||
int width_count;
|
||||
short width_default; /* in 1000 units */
|
||||
short *width_table; /* in 1000 units */
|
||||
|
||||
/* cached glyph metrics */
|
||||
float **advance_cache;
|
||||
|
||||
/* cached encoding lookup */
|
||||
uint16_t *encoding_cache[256];
|
||||
|
||||
/* cached md5sum for caching */
|
||||
int has_digest;
|
||||
unsigned char digest[16];
|
||||
|
||||
/* Which font to use in a collection. */
|
||||
int subfont;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,818 @@
|
||||
// Copyright (C) 2004-2022 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_MATH_H
|
||||
#define MUPDF_FITZ_MATH_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
Multiply scaled two integers in the 0..255 range
|
||||
*/
|
||||
static inline int fz_mul255(int a, int b)
|
||||
{
|
||||
/* see Jim Blinn's book "Dirty Pixels" for how this works */
|
||||
int x = a * b + 128;
|
||||
x += x >> 8;
|
||||
return x >> 8;
|
||||
}
|
||||
|
||||
/**
|
||||
Undo alpha premultiplication.
|
||||
*/
|
||||
static inline int fz_div255(int c, int a)
|
||||
{
|
||||
return a ? c * (255 * 256 / a) >> 8 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Expand a value A from the 0...255 range to the 0..256 range
|
||||
*/
|
||||
#define FZ_EXPAND(A) ((A)+((A)>>7))
|
||||
|
||||
/**
|
||||
Combine values A (in any range) and B (in the 0..256 range),
|
||||
to give a single value in the same range as A was.
|
||||
*/
|
||||
#define FZ_COMBINE(A,B) (((A)*(B))>>8)
|
||||
|
||||
/**
|
||||
Combine values A and C (in the same (any) range) and B and D (in
|
||||
the 0..256 range), to give a single value in the same range as A
|
||||
and C were.
|
||||
*/
|
||||
#define FZ_COMBINE2(A,B,C,D) (((A) * (B) + (C) * (D))>>8)
|
||||
|
||||
/**
|
||||
Blend SRC and DST (in the same range) together according to
|
||||
AMOUNT (in the 0...256 range).
|
||||
*/
|
||||
#define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8)
|
||||
|
||||
/**
|
||||
Range checking atof
|
||||
*/
|
||||
float fz_atof(const char *s);
|
||||
|
||||
/**
|
||||
atoi that copes with NULL
|
||||
*/
|
||||
int fz_atoi(const char *s);
|
||||
|
||||
/**
|
||||
64bit atoi that copes with NULL
|
||||
*/
|
||||
int64_t fz_atoi64(const char *s);
|
||||
|
||||
/**
|
||||
Some standard math functions, done as static inlines for speed.
|
||||
People with compilers that do not adequately implement inline
|
||||
may like to reimplement these using macros.
|
||||
*/
|
||||
static inline float fz_abs(float f)
|
||||
{
|
||||
return (f < 0 ? -f : f);
|
||||
}
|
||||
|
||||
static inline int fz_absi(int i)
|
||||
{
|
||||
return (i < 0 ? -i : i);
|
||||
}
|
||||
|
||||
static inline float fz_min(float a, float b)
|
||||
{
|
||||
return (a < b ? a : b);
|
||||
}
|
||||
|
||||
static inline int fz_mini(int a, int b)
|
||||
{
|
||||
return (a < b ? a : b);
|
||||
}
|
||||
|
||||
static inline size_t fz_minz(size_t a, size_t b)
|
||||
{
|
||||
return (a < b ? a : b);
|
||||
}
|
||||
|
||||
static inline int64_t fz_mini64(int64_t a, int64_t b)
|
||||
{
|
||||
return (a < b ? a : b);
|
||||
}
|
||||
|
||||
static inline float fz_max(float a, float b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
static inline int fz_maxi(int a, int b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
static inline size_t fz_maxz(size_t a, size_t b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
static inline int64_t fz_maxi64(int64_t a, int64_t b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
static inline float fz_clamp(float x, float min, float max)
|
||||
{
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
static inline int fz_clampi(int x, int min, int max)
|
||||
{
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
static inline int64_t fz_clamp64(int64_t x, int64_t min, int64_t max)
|
||||
{
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
static inline double fz_clampd(double x, double min, double max)
|
||||
{
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
static inline void *fz_clampp(void *x, void *min, void *max)
|
||||
{
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
#define DIV_BY_ZERO(a, b, min, max) (((a) < 0) ^ ((b) < 0) ? (min) : (max))
|
||||
|
||||
/**
|
||||
fz_point is a point in a two-dimensional space.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float x, y;
|
||||
} fz_point;
|
||||
|
||||
static inline fz_point fz_make_point(float x, float y)
|
||||
{
|
||||
fz_point p = { x, y };
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
fz_rect is a rectangle represented by two diagonally opposite
|
||||
corners at arbitrary coordinates.
|
||||
|
||||
Rectangles are always axis-aligned with the X- and Y- axes. We
|
||||
wish to distinguish rectangles in 3 categories; infinite, finite,
|
||||
and invalid. Zero area rectangles are a sub-category of finite
|
||||
ones.
|
||||
|
||||
For all valid rectangles, x0 <= x1 and y0 <= y1 in all cases.
|
||||
Infinite rectangles have x0 = y0 = FZ_MIN_INF_RECT,
|
||||
x1 = y1 = FZ_MAX_INF_RECT. For any non infinite valid rectangle,
|
||||
the area is defined as (x1 - x0) * (y1 - y0).
|
||||
|
||||
To check for empty or infinite rectangles use fz_is_empty_rect
|
||||
and fz_is_infinite_rect. To check for valid rectangles use
|
||||
fz_is_valid_rect.
|
||||
|
||||
We choose this representation, so that we can easily distinguish
|
||||
the difference between intersecting 2 valid rectangles and
|
||||
getting an invalid one, as opposed to getting a zero area one
|
||||
(which nonetheless has valid bounds within the plane).
|
||||
|
||||
x0, y0: The top left corner.
|
||||
|
||||
x1, y1: The bottom right corner.
|
||||
|
||||
We choose FZ_{MIN,MAX}_INF_RECT to be the largest 32bit signed
|
||||
integer values that survive roundtripping to floats.
|
||||
*/
|
||||
#define FZ_MIN_INF_RECT ((int)0x80000000)
|
||||
#define FZ_MAX_INF_RECT ((int)0x7fffff80)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x0, y0;
|
||||
float x1, y1;
|
||||
} fz_rect;
|
||||
|
||||
static inline fz_rect fz_make_rect(float x0, float y0, float x1, float y1)
|
||||
{
|
||||
fz_rect r = { x0, y0, x1, y1 };
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
fz_irect is a rectangle using integers instead of floats.
|
||||
|
||||
It's used in the draw device and for pixmap dimensions.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int x0, y0;
|
||||
int x1, y1;
|
||||
} fz_irect;
|
||||
|
||||
static inline fz_irect fz_make_irect(int x0, int y0, int x1, int y1)
|
||||
{
|
||||
fz_irect r = { x0, y0, x1, y1 };
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
A rectangle with sides of length one.
|
||||
|
||||
The bottom left corner is at (0, 0) and the top right corner
|
||||
is at (1, 1).
|
||||
*/
|
||||
FZ_DATA extern const fz_rect fz_unit_rect;
|
||||
|
||||
/**
|
||||
An empty rectangle with an area equal to zero.
|
||||
*/
|
||||
FZ_DATA extern const fz_rect fz_empty_rect;
|
||||
FZ_DATA extern const fz_irect fz_empty_irect;
|
||||
|
||||
/**
|
||||
An infinite rectangle.
|
||||
*/
|
||||
FZ_DATA extern const fz_rect fz_infinite_rect;
|
||||
FZ_DATA extern const fz_irect fz_infinite_irect;
|
||||
|
||||
/**
|
||||
Check if rectangle is empty.
|
||||
|
||||
An empty rectangle is defined as one whose area is zero.
|
||||
All invalid rectangles are empty.
|
||||
*/
|
||||
static inline int fz_is_empty_rect(fz_rect r)
|
||||
{
|
||||
return (r.x0 >= r.x1 || r.y0 >= r.y1);
|
||||
}
|
||||
|
||||
static inline int fz_is_empty_irect(fz_irect r)
|
||||
{
|
||||
return (r.x0 >= r.x1 || r.y0 >= r.y1);
|
||||
}
|
||||
|
||||
/**
|
||||
Check if rectangle is infinite.
|
||||
*/
|
||||
static inline int fz_is_infinite_rect(fz_rect r)
|
||||
{
|
||||
return (r.x0 == FZ_MIN_INF_RECT && r.x1 == FZ_MAX_INF_RECT &&
|
||||
r.y0 == FZ_MIN_INF_RECT && r.y1 == FZ_MAX_INF_RECT);
|
||||
}
|
||||
|
||||
/**
|
||||
Check if an integer rectangle
|
||||
is infinite.
|
||||
*/
|
||||
static inline int fz_is_infinite_irect(fz_irect r)
|
||||
{
|
||||
return (r.x0 == FZ_MIN_INF_RECT && r.x1 == FZ_MAX_INF_RECT &&
|
||||
r.y0 == FZ_MIN_INF_RECT && r.y1 == FZ_MAX_INF_RECT);
|
||||
}
|
||||
|
||||
/**
|
||||
Check if rectangle is valid.
|
||||
*/
|
||||
static inline int fz_is_valid_rect(fz_rect r)
|
||||
{
|
||||
return (r.x0 <= r.x1 && r.y0 <= r.y1);
|
||||
}
|
||||
|
||||
/**
|
||||
Check if an integer rectangle is valid.
|
||||
*/
|
||||
static inline int fz_is_valid_irect(fz_irect r)
|
||||
{
|
||||
return (r.x0 <= r.x1 && r.y0 <= r.y1);
|
||||
}
|
||||
|
||||
/**
|
||||
Return the width of an irect. Invalid irects return 0.
|
||||
*/
|
||||
static inline unsigned int
|
||||
fz_irect_width(fz_irect r)
|
||||
{
|
||||
unsigned int w;
|
||||
if (r.x0 >= r.x1)
|
||||
return 0;
|
||||
/* Check for w overflowing. This should never happen, but
|
||||
* if it does, it's pretty likely an indication of a severe
|
||||
* problem. */
|
||||
w = (unsigned int)r.x1 - r.x0;
|
||||
assert((int)w >= 0);
|
||||
if ((int)w < 0)
|
||||
return 0;
|
||||
return (int)w;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the height of an irect. Invalid irects return 0.
|
||||
*/
|
||||
static inline int
|
||||
fz_irect_height(fz_irect r)
|
||||
{
|
||||
unsigned int h;
|
||||
if (r.y0 >= r.y1)
|
||||
return 0;
|
||||
/* Check for h overflowing. This should never happen, but
|
||||
* if it does, it's pretty likely an indication of a severe
|
||||
* problem. */
|
||||
h = (unsigned int)(r.y1 - r.y0);
|
||||
assert((int)h >= 0);
|
||||
if ((int)h < 0)
|
||||
return 0;
|
||||
return (int)h;
|
||||
}
|
||||
|
||||
/**
|
||||
fz_matrix is a row-major 3x3 matrix used for representing
|
||||
transformations of coordinates throughout MuPDF.
|
||||
|
||||
Since all points reside in a two-dimensional space, one vector
|
||||
is always a constant unit vector; hence only some elements may
|
||||
vary in a matrix. Below is how the elements map between
|
||||
different representations.
|
||||
|
||||
/ a b 0 \
|
||||
| c d 0 | normally represented as [ a b c d e f ].
|
||||
\ e f 1 /
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float a, b, c, d, e, f;
|
||||
} fz_matrix;
|
||||
|
||||
/**
|
||||
Identity transform matrix.
|
||||
*/
|
||||
FZ_DATA extern const fz_matrix fz_identity;
|
||||
|
||||
static inline fz_matrix fz_make_matrix(float a, float b, float c, float d, float e, float f)
|
||||
{
|
||||
fz_matrix m = { a, b, c, d, e, f };
|
||||
return m;
|
||||
}
|
||||
|
||||
static inline int fz_is_identity(fz_matrix m)
|
||||
{
|
||||
return m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Multiply two matrices.
|
||||
|
||||
The order of the two matrices are important since matrix
|
||||
multiplication is not commutative.
|
||||
|
||||
Returns result.
|
||||
*/
|
||||
fz_matrix fz_concat(fz_matrix left, fz_matrix right);
|
||||
|
||||
/**
|
||||
Create a scaling matrix.
|
||||
|
||||
The returned matrix is of the form [ sx 0 0 sy 0 0 ].
|
||||
|
||||
m: Pointer to the matrix to populate
|
||||
|
||||
sx, sy: Scaling factors along the X- and Y-axes. A scaling
|
||||
factor of 1.0 will not cause any scaling along the relevant
|
||||
axis.
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix fz_scale(float sx, float sy);
|
||||
|
||||
/**
|
||||
Scale a matrix by premultiplication.
|
||||
|
||||
m: Pointer to the matrix to scale
|
||||
|
||||
sx, sy: Scaling factors along the X- and Y-axes. A scaling
|
||||
factor of 1.0 will not cause any scaling along the relevant
|
||||
axis.
|
||||
|
||||
Returns m (updated).
|
||||
*/
|
||||
fz_matrix fz_pre_scale(fz_matrix m, float sx, float sy);
|
||||
|
||||
/**
|
||||
Scale a matrix by postmultiplication.
|
||||
|
||||
m: Pointer to the matrix to scale
|
||||
|
||||
sx, sy: Scaling factors along the X- and Y-axes. A scaling
|
||||
factor of 1.0 will not cause any scaling along the relevant
|
||||
axis.
|
||||
|
||||
Returns m (updated).
|
||||
*/
|
||||
fz_matrix fz_post_scale(fz_matrix m, float sx, float sy);
|
||||
|
||||
/**
|
||||
Create a shearing matrix.
|
||||
|
||||
The returned matrix is of the form [ 1 sy sx 1 0 0 ].
|
||||
|
||||
m: pointer to place to store returned matrix
|
||||
|
||||
sx, sy: Shearing factors. A shearing factor of 0.0 will not
|
||||
cause any shearing along the relevant axis.
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix fz_shear(float sx, float sy);
|
||||
|
||||
/**
|
||||
Premultiply a matrix with a shearing matrix.
|
||||
|
||||
The shearing matrix is of the form [ 1 sy sx 1 0 0 ].
|
||||
|
||||
m: pointer to matrix to premultiply
|
||||
|
||||
sx, sy: Shearing factors. A shearing factor of 0.0 will not
|
||||
cause any shearing along the relevant axis.
|
||||
|
||||
Returns m (updated).
|
||||
*/
|
||||
fz_matrix fz_pre_shear(fz_matrix m, float sx, float sy);
|
||||
|
||||
/**
|
||||
Create a rotation matrix.
|
||||
|
||||
The returned matrix is of the form
|
||||
[ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ].
|
||||
|
||||
m: Pointer to place to store matrix
|
||||
|
||||
degrees: Degrees of counter clockwise rotation. Values less
|
||||
than zero and greater than 360 are handled as expected.
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix fz_rotate(float degrees);
|
||||
|
||||
/**
|
||||
Rotate a transformation by premultiplying.
|
||||
|
||||
The premultiplied matrix is of the form
|
||||
[ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ].
|
||||
|
||||
m: Pointer to matrix to premultiply.
|
||||
|
||||
degrees: Degrees of counter clockwise rotation. Values less
|
||||
than zero and greater than 360 are handled as expected.
|
||||
|
||||
Returns m (updated).
|
||||
*/
|
||||
fz_matrix fz_pre_rotate(fz_matrix m, float degrees);
|
||||
|
||||
/**
|
||||
Create a translation matrix.
|
||||
|
||||
The returned matrix is of the form [ 1 0 0 1 tx ty ].
|
||||
|
||||
m: A place to store the created matrix.
|
||||
|
||||
tx, ty: Translation distances along the X- and Y-axes. A
|
||||
translation of 0 will not cause any translation along the
|
||||
relevant axis.
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix fz_translate(float tx, float ty);
|
||||
|
||||
/**
|
||||
Translate a matrix by premultiplication.
|
||||
|
||||
m: The matrix to translate
|
||||
|
||||
tx, ty: Translation distances along the X- and Y-axes. A
|
||||
translation of 0 will not cause any translation along the
|
||||
relevant axis.
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix fz_pre_translate(fz_matrix m, float tx, float ty);
|
||||
|
||||
/**
|
||||
Create transform matrix to draw page
|
||||
at a given resolution and rotation. Adjusts the scaling
|
||||
factors so that the page covers whole number of
|
||||
pixels and adjust the page origin to be at 0,0.
|
||||
*/
|
||||
fz_matrix fz_transform_page(fz_rect mediabox, float resolution, float rotate);
|
||||
|
||||
/**
|
||||
Create an inverse matrix.
|
||||
|
||||
inverse: Place to store inverse matrix.
|
||||
|
||||
matrix: Matrix to invert. A degenerate matrix, where the
|
||||
determinant is equal to zero, can not be inverted and the
|
||||
original matrix is returned instead.
|
||||
|
||||
Returns inverse.
|
||||
*/
|
||||
fz_matrix fz_invert_matrix(fz_matrix matrix);
|
||||
|
||||
/**
|
||||
Attempt to create an inverse matrix.
|
||||
|
||||
inverse: Place to store inverse matrix.
|
||||
|
||||
matrix: Matrix to invert. A degenerate matrix, where the
|
||||
determinant is equal to zero, can not be inverted.
|
||||
|
||||
Returns 1 if matrix is degenerate (singular), or 0 otherwise.
|
||||
*/
|
||||
int fz_try_invert_matrix(fz_matrix *inv, fz_matrix src);
|
||||
|
||||
/**
|
||||
Check if a transformation is rectilinear.
|
||||
|
||||
Rectilinear means that no shearing is present and that any
|
||||
rotations present are a multiple of 90 degrees. Usually this
|
||||
is used to make sure that axis-aligned rectangles before the
|
||||
transformation are still axis-aligned rectangles afterwards.
|
||||
*/
|
||||
int fz_is_rectilinear(fz_matrix m);
|
||||
|
||||
/**
|
||||
Calculate average scaling factor of matrix.
|
||||
*/
|
||||
float fz_matrix_expansion(fz_matrix m);
|
||||
|
||||
/**
|
||||
Compute intersection of two rectangles.
|
||||
|
||||
Given two rectangles, update the first to be the smallest
|
||||
axis-aligned rectangle that covers the area covered by both
|
||||
given rectangles. If either rectangle is empty then the
|
||||
intersection is also empty. If either rectangle is infinite
|
||||
then the intersection is simply the non-infinite rectangle.
|
||||
Should both rectangles be infinite, then the intersection is
|
||||
also infinite.
|
||||
*/
|
||||
fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
|
||||
|
||||
/**
|
||||
Compute intersection of two bounding boxes.
|
||||
|
||||
Similar to fz_intersect_rect but operates on two bounding
|
||||
boxes instead of two rectangles.
|
||||
*/
|
||||
fz_irect fz_intersect_irect(fz_irect a, fz_irect b);
|
||||
|
||||
/**
|
||||
Compute union of two rectangles.
|
||||
|
||||
Given two rectangles, update the first to be the smallest
|
||||
axis-aligned rectangle that encompasses both given rectangles.
|
||||
If either rectangle is infinite then the union is also infinite.
|
||||
If either rectangle is empty then the union is simply the
|
||||
non-empty rectangle. Should both rectangles be empty, then the
|
||||
union is also empty.
|
||||
*/
|
||||
fz_rect fz_union_rect(fz_rect a, fz_rect b);
|
||||
|
||||
/**
|
||||
Convert a rect into the minimal bounding box
|
||||
that covers the rectangle.
|
||||
|
||||
Coordinates in a bounding box are integers, so rounding of the
|
||||
rects coordinates takes place. The top left corner is rounded
|
||||
upwards and left while the bottom right corner is rounded
|
||||
downwards and to the right.
|
||||
*/
|
||||
fz_irect fz_irect_from_rect(fz_rect rect);
|
||||
|
||||
/**
|
||||
Round rectangle coordinates.
|
||||
|
||||
Coordinates in a bounding box are integers, so rounding of the
|
||||
rects coordinates takes place. The top left corner is rounded
|
||||
upwards and left while the bottom right corner is rounded
|
||||
downwards and to the right.
|
||||
|
||||
This differs from fz_irect_from_rect, in that fz_irect_from_rect
|
||||
slavishly follows the numbers (i.e any slight over/under
|
||||
calculations can cause whole extra pixels to be added).
|
||||
fz_round_rect allows for a small amount of rounding error when
|
||||
calculating the bbox.
|
||||
*/
|
||||
fz_irect fz_round_rect(fz_rect rect);
|
||||
|
||||
/**
|
||||
Convert a bbox into a rect.
|
||||
|
||||
For our purposes, a rect can represent all the values we meet in
|
||||
a bbox, so nothing can go wrong.
|
||||
|
||||
rect: A place to store the generated rectangle.
|
||||
|
||||
bbox: The bbox to convert.
|
||||
|
||||
Returns rect (updated).
|
||||
*/
|
||||
fz_rect fz_rect_from_irect(fz_irect bbox);
|
||||
|
||||
/**
|
||||
Expand a bbox by a given amount in all directions.
|
||||
*/
|
||||
fz_rect fz_expand_rect(fz_rect b, float expand);
|
||||
fz_irect fz_expand_irect(fz_irect a, int expand);
|
||||
|
||||
/**
|
||||
Expand a bbox to include a given point.
|
||||
To create a rectangle that encompasses a sequence of points, the
|
||||
rectangle must first be set to be the empty rectangle at one of
|
||||
the points before including the others.
|
||||
*/
|
||||
fz_rect fz_include_point_in_rect(fz_rect r, fz_point p);
|
||||
|
||||
/**
|
||||
Translate bounding box.
|
||||
|
||||
Translate a bbox by a given x and y offset. Allows for overflow.
|
||||
*/
|
||||
fz_rect fz_translate_rect(fz_rect a, float xoff, float yoff);
|
||||
fz_irect fz_translate_irect(fz_irect a, int xoff, int yoff);
|
||||
|
||||
/**
|
||||
Test rectangle inclusion.
|
||||
|
||||
Return true if a entirely contains b.
|
||||
*/
|
||||
int fz_contains_rect(fz_rect a, fz_rect b);
|
||||
|
||||
/**
|
||||
Apply a transformation to a point.
|
||||
|
||||
transform: Transformation matrix to apply. See fz_concat,
|
||||
fz_scale, fz_rotate and fz_translate for how to create a
|
||||
matrix.
|
||||
|
||||
point: Pointer to point to update.
|
||||
|
||||
Returns transform (unchanged).
|
||||
*/
|
||||
fz_point fz_transform_point(fz_point point, fz_matrix m);
|
||||
fz_point fz_transform_point_xy(float x, float y, fz_matrix m);
|
||||
|
||||
/**
|
||||
Apply a transformation to a vector.
|
||||
|
||||
transform: Transformation matrix to apply. See fz_concat,
|
||||
fz_scale and fz_rotate for how to create a matrix. Any
|
||||
translation will be ignored.
|
||||
|
||||
vector: Pointer to vector to update.
|
||||
*/
|
||||
fz_point fz_transform_vector(fz_point vector, fz_matrix m);
|
||||
|
||||
/**
|
||||
Apply a transform to a rectangle.
|
||||
|
||||
After the four corner points of the axis-aligned rectangle
|
||||
have been transformed it may not longer be axis-aligned. So a
|
||||
new axis-aligned rectangle is created covering at least the
|
||||
area of the transformed rectangle.
|
||||
|
||||
transform: Transformation matrix to apply. See fz_concat,
|
||||
fz_scale and fz_rotate for how to create a matrix.
|
||||
|
||||
rect: Rectangle to be transformed. The two special cases
|
||||
fz_empty_rect and fz_infinite_rect, may be used but are
|
||||
returned unchanged as expected.
|
||||
*/
|
||||
fz_rect fz_transform_rect(fz_rect rect, fz_matrix m);
|
||||
|
||||
/**
|
||||
Normalize a vector to length one.
|
||||
*/
|
||||
fz_point fz_normalize_vector(fz_point p);
|
||||
|
||||
/**
|
||||
Grid fit a matrix.
|
||||
|
||||
as_tiled = 0 => adjust the matrix so that the image of the unit
|
||||
square completely covers any pixel that was touched by the
|
||||
image of the unit square under the original matrix.
|
||||
|
||||
as_tiled = 1 => adjust the matrix so that the corners of the
|
||||
image of the unit square align with the closest integer corner
|
||||
of the image of the unit square under the original matrix.
|
||||
*/
|
||||
fz_matrix fz_gridfit_matrix(int as_tiled, fz_matrix m);
|
||||
|
||||
/**
|
||||
Find the largest expansion performed by this matrix.
|
||||
(i.e. max(abs(m.a),abs(m.b),abs(m.c),abs(m.d))
|
||||
*/
|
||||
float fz_matrix_max_expansion(fz_matrix m);
|
||||
|
||||
/**
|
||||
A representation for a region defined by 4 points.
|
||||
|
||||
The significant difference between quads and rects is that
|
||||
the edges of quads are not axis aligned.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
fz_point ul, ur, ll, lr;
|
||||
} fz_quad;
|
||||
|
||||
/**
|
||||
Inline convenience construction function.
|
||||
*/
|
||||
static inline fz_quad fz_make_quad(
|
||||
float ul_x, float ul_y,
|
||||
float ur_x, float ur_y,
|
||||
float ll_x, float ll_y,
|
||||
float lr_x, float lr_y)
|
||||
{
|
||||
fz_quad q = {
|
||||
{ ul_x, ul_y },
|
||||
{ ur_x, ur_y },
|
||||
{ ll_x, ll_y },
|
||||
{ lr_x, lr_y },
|
||||
};
|
||||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a rect to a quad (losslessly).
|
||||
*/
|
||||
fz_quad fz_quad_from_rect(fz_rect r);
|
||||
|
||||
/**
|
||||
Convert a quad to the smallest rect that covers it.
|
||||
*/
|
||||
fz_rect fz_rect_from_quad(fz_quad q);
|
||||
|
||||
/**
|
||||
Transform a quad by a matrix.
|
||||
*/
|
||||
fz_quad fz_transform_quad(fz_quad q, fz_matrix m);
|
||||
|
||||
/**
|
||||
Inclusion test for quads.
|
||||
*/
|
||||
int fz_is_point_inside_quad(fz_point p, fz_quad q);
|
||||
|
||||
/**
|
||||
Inclusion test for rects. (Rect is assumed to be open, i.e.
|
||||
top right corner is not included).
|
||||
*/
|
||||
int fz_is_point_inside_rect(fz_point p, fz_rect r);
|
||||
|
||||
/**
|
||||
Inclusion test for irects. (Rect is assumed to be open, i.e.
|
||||
top right corner is not included).
|
||||
*/
|
||||
int fz_is_point_inside_irect(int x, int y, fz_irect r);
|
||||
|
||||
/**
|
||||
Inclusion test for quad in quad.
|
||||
|
||||
This may break down if quads are not 'well formed'.
|
||||
*/
|
||||
int fz_is_quad_inside_quad(fz_quad needle, fz_quad haystack);
|
||||
|
||||
/**
|
||||
Intersection test for quads.
|
||||
|
||||
This may break down if quads are not 'well formed'.
|
||||
*/
|
||||
int fz_is_quad_intersecting_quad(fz_quad a, fz_quad b);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_GETOPT_H
|
||||
#define MUPDF_FITZ_GETOPT_H
|
||||
|
||||
#include "export.h"
|
||||
|
||||
/**
|
||||
Simple functions/variables for use in tools.
|
||||
*/
|
||||
extern int fz_getopt(int nargc, char * const *nargv, const char *ostr);
|
||||
FZ_DATA extern int fz_optind;
|
||||
FZ_DATA extern char *fz_optarg;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_GLYPH_CACHE_H
|
||||
#define MUPDF_FITZ_GLYPH_CACHE_H
|
||||
|
||||
#include "mupdf/fitz/context.h"
|
||||
#include "mupdf/fitz/geometry.h"
|
||||
#include "mupdf/fitz/font.h"
|
||||
#include "mupdf/fitz/pixmap.h"
|
||||
#include "mupdf/fitz/device.h"
|
||||
|
||||
/**
|
||||
Purge all the glyphs from the cache.
|
||||
*/
|
||||
void fz_purge_glyph_cache(fz_context *ctx);
|
||||
|
||||
/**
|
||||
Create a pixmap containing a rendered glyph.
|
||||
|
||||
Lookup gid from font, clip it with scissor, and rendering it
|
||||
with aa bits of antialiasing into a new pixmap.
|
||||
|
||||
The caller takes ownership of the pixmap and so must free it.
|
||||
|
||||
Note: This function is no longer used for normal rendering
|
||||
operations, and is kept around just because we use it in the
|
||||
app. It should be considered "at risk" of removal from the API.
|
||||
*/
|
||||
fz_pixmap *fz_render_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, const fz_irect *scissor, int aa);
|
||||
|
||||
/**
|
||||
Nasty PDF interpreter specific hernia, required to allow the
|
||||
interpreter to replay glyphs from a type3 font directly into
|
||||
the target device.
|
||||
|
||||
This is only used in exceptional circumstances (such as type3
|
||||
glyphs that inherit current graphics state, or nested type3
|
||||
glyphs).
|
||||
*/
|
||||
void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate, fz_default_colorspaces *def_cs);
|
||||
|
||||
/**
|
||||
Force a type3 font to cache the displaylist for a given glyph
|
||||
id.
|
||||
|
||||
This caching can involve reading the underlying file, so must
|
||||
happen ahead of time, so we aren't suddenly forced to read the
|
||||
file while playing a displaylist back.
|
||||
*/
|
||||
void fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid);
|
||||
|
||||
/**
|
||||
Dump debug statistics for the glyph cache.
|
||||
*/
|
||||
void fz_dump_glyph_cache_stats(fz_context *ctx, fz_output *out);
|
||||
|
||||
/**
|
||||
Perform subpixel quantisation and adjustment on a glyph matrix.
|
||||
|
||||
ctm: On entry, the desired 'ideal' transformation for a glyph.
|
||||
On exit, adjusted to a (very similar) transformation quantised
|
||||
for subpixel caching.
|
||||
|
||||
subpix_ctm: Initialised by the routine to the transform that
|
||||
should be used to render the glyph.
|
||||
|
||||
qe, qf: which subpixel position we quantised to.
|
||||
|
||||
Returns: the size of the glyph.
|
||||
|
||||
Note: This is currently only exposed for use in our app. It
|
||||
should be considered "at risk" of removal from the API.
|
||||
*/
|
||||
float fz_subpixel_adjust(fz_context *ctx, fz_matrix *ctm, fz_matrix *subpix_ctm, unsigned char *qe, unsigned char *qf);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2004-2021 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
| ||||