master
会PS的小码农 4 years ago
commit db8ce35700

2
.gitignore vendored

@ -0,0 +1,2 @@
/img
!/img/readme.md

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 wejectchan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,22 @@
version: "{build}"
clone_depth: 1
clone_folder: c:\gopath\src\github.com\gen2brain\go-fitz
environment:
GOPATH: c:\gopath
MSYS_PATH: c:\msys64
CGO_ENABLED: 1
GOARCH: 386
CC: i686-w64-mingw32-gcc
install:
- echo %GOPATH%
- echo %MSYS_PATH%
- set PATH=%GOPATH%\bin;c:\go\bin;%MSYS_PATH%\usr\bin;%MSYS_PATH%\mingw32\bin;%PATH%
- go version
- go env
build_script:
- bash -lc "cd /c/gopath/src/github.com/gen2brain/go-fitz && go build"

@ -0,0 +1,10 @@
language: go
go:
- 1.12.x
install:
- go get -tags nopie -t -v ./...
script:
- go build -tags nopie

@ -0,0 +1 @@
Milan Nikolic <gen2brain@gmail.com>

@ -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,106 @@
## go-fitz
[![TravisCI Build Status](https://travis-ci.org/gen2brain/go-fitz.svg?branch=master)](https://travis-ci.org/gen2brain/go-fitz)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/vuuoq9epsd1sa007?svg=true)](https://ci.appveyor.com/project/gen2brain/go-fitz)
[![GoDoc](https://godoc.org/github.com/gen2brain/go-fitz?status.svg)](https://godoc.org/github.com/gen2brain/go-fitz)
[![Go Report Card](https://goreportcard.com/badge/github.com/gen2brain/go-fitz?branch=master)](https://goreportcard.com/report/github.com/gen2brain/go-fitz)
Go wrapper for [MuPDF](http://mupdf.com/) fitz library that can extract pages from PDF and EPUB documents as images, text, html or svg.
### Install
go get -u github.com/gen2brain/go-fitz
### Build tags
* `extlib` - use external MuPDF library
* `static` - build with static external MuPDF library (used with `extlib`)
* `nopie` - use this with GCC older then 7
### Example
```go
package main
import (
"fmt"
"image/jpeg"
"io/ioutil"
"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 := ioutil.TempDir(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()
}
// 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()
}
}
```

@ -0,0 +1,103 @@
package fitz
import (
"fmt"
"image/jpeg"
"io/ioutil"
"os"
"path/filepath"
)
func ExampleNew() {
doc, err := New("test.pdf")
if err != nil {
panic(err)
}
defer doc.Close()
tmpDir, err := ioutil.TempDir(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,470 @@
// 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;
*/
import "C"
import (
"errors"
"image"
"io"
"io/ioutil"
"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_s
doc *C.struct_fz_document_s
mtx sync.Mutex
}
// 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
}
// 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_s)(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.fz_open_document(f.ctx, cfilename)
if f.doc == nil {
err = ErrOpenDocument
}
ret := C.fz_needs_password(f.ctx, f.doc)
v := bool(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_s)(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)
data := (*C.uchar)(C.CBytes(b))
stream := C.fz_open_memory(f.ctx, data, C.size_t(len(b)))
if stream == nil {
err = ErrOpenMemory
return
}
cmagic := C.CString(contentType(b))
defer C.free(unsafe.Pointer(cmagic))
f.doc = C.fz_open_document_with_stream(f.ctx, cmagic, stream)
if f.doc == nil {
err = ErrOpenDocument
}
ret := C.fz_needs_password(f.ctx, f.doc)
v := bool(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 := ioutil.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, 500.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
C.fz_bound_page(f.ctx, page, &bounds)
var ctm C.fz_matrix
C.fz_scale(&ctm, C.float(dpi/72), C.float(dpi/72))
var bbox C.fz_irect
C.fz_transform_rect(&bounds, &ctm)
C.fz_round_rect(&bbox, &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
}
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
C.fz_bound_page(f.ctx, page, &bounds)
var ctm C.fz_matrix
C.fz_scale(&ctm, C.float(dpi/72), C.float(dpi/72))
var bbox C.fz_irect
C.fz_transform_rect(&bounds, &ctm)
C.fz_round_rect(&bbox, &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, nil)
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
}
// 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
C.fz_bound_page(f.ctx, page, &bounds)
var ctm C.fz_matrix
C.fz_scale(&ctm, 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
C.fz_bound_page(f.ctx, page, &bounds)
var ctm C.fz_matrix
C.fz_scale(&ctm, 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)
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
C.fz_bound_page(f.ctx, page, &bounds)
var ctm C.fz_matrix
C.fz_scale(&ctm, C.float(72.0/72), C.float(72.0/72))
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)
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
}
// Close closes the underlying fitz document.
func (f *Document) Close() error {
C.fz_drop_document(f.ctx, f.doc)
C.fz_drop_context(f.ctx)
return nil
}
// contentType returns document MIME type.
func contentType(b []byte) string {
var mtype string
if len(b) > 3 && b[0] == 0x25 && b[1] == 0x50 && b[2] == 0x44 && b[3] == 0x46 {
mtype = "application/pdf"
} else if len(b) > 57 && b[0] == 0x50 && b[1] == 0x4B && b[2] == 0x3 && b[3] == 0x4 && 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 {
mtype = "application/epub+zip"
}
return mtype
}

@ -0,0 +1,19 @@
// +build !extlib
package fitz
/*
#cgo CFLAGS: -Iinclude
#cgo linux,386 LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_386 -lmupdfthird_linux_386 -lm
#cgo linux,!nopie,amd64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_amd64 -lmupdfthird_linux_amd64 -lm
#cgo linux,nopie,amd64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_amd64_nopie -lmupdfthird_linux_amd64_nopie -lm
#cgo linux,!android,arm LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_arm -lmupdfthird_linux_arm -lm
#cgo linux,!android,arm64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_linux_arm64 -lmupdfthird_linux_arm64 -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
#cgo windows,amd64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_windows_amd64 -lmupdfthird_windows_amd64 -lm -lcomdlg32 -lgdi32
#cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/libs -lmupdf_darwin_amd64 -lmupdfthird_darwin_amd64 -lm
*/
import "C"

@ -0,0 +1,11 @@
// +build extlib
package fitz
/*
#cgo !static LDFLAGS: -lmupdf -lm
#cgo static LDFLAGS: -lmupdf -lm -lmupdfthird
#cgo android LDFLAGS: -llog
#cgo windows LDFLAGS: -lcomdlg32 -lgdi32
*/
import "C"

@ -0,0 +1,210 @@
package fitz
import (
"fmt"
"image/jpeg"
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func TestImage(t *testing.T) {
doc, err := 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++ {
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 := ioutil.ReadFile(filepath.Join("testdata", "test.pdf"))
if err != nil {
t.Error(err)
}
doc, err := NewFromMemory(b)
if err != nil {
t.Error(err)
}
defer doc.Close()
tmpDir, err := ioutil.TempDir(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 TestText(t *testing.T) {
doc, err := 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++ {
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 := 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 := 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 := 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 := 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"))
}
}

@ -0,0 +1,78 @@
#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/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/output.h"
#include "mupdf/fitz/archive.h"
/* Resources */
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/colorspace.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/glyph.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/color-management.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/annotation.h"
#include "mupdf/fitz/util.h"
/* Output formats */
#include "mupdf/fitz/writer.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/output-pnm.h"
#include "mupdf/fitz/output-png.h"
#include "mupdf/fitz/output-pwg.h"
#include "mupdf/fitz/output-pcl.h"
#include "mupdf/fitz/output-pclm.h"
#include "mupdf/fitz/output-ps.h"
#include "mupdf/fitz/output-psd.h"
#include "mupdf/fitz/output-svg.h"
#include "mupdf/fitz/output-tga.h"
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,43 @@
#ifndef MUPDF_FITZ_ANNOTATION_H
#define MUPDF_FITZ_ANNOTATION_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/document.h"
/*
fz_new_annot_of_size: Create and initialize an annotation struct.
*/
fz_annot *fz_new_annot_of_size(fz_context *ctx, int size);
#define fz_new_derived_annot(CTX, TYPE) \
((TYPE *)Memento_label(fz_new_annot_of_size(CTX,sizeof(TYPE)),#TYPE))
/*
fz_keep_annot: Take a new reference to an annotation.
*/
fz_annot *fz_keep_annot(fz_context *ctx, fz_annot *annot);
/*
fz_drop_annot: Drop a reference to an annotation. If the
reference count reaches zero, annot will be destroyed.
*/
void fz_drop_annot(fz_context *ctx, fz_annot *annot);
/*
fz_first_annot: Return a pointer to the first annotation on a page.
*/
fz_annot *fz_first_annot(fz_context *ctx, fz_page *page);
/*
fz_next_annot: Return a pointer to the next annotation on a page.
*/
fz_annot *fz_next_annot(fz_context *ctx, fz_annot *annot);
/*
fz_bound_annot: Return the bounding rectangle of the annotation.
*/
fz_rect *fz_bound_annot(fz_context *ctx, fz_annot *annot, fz_rect *rect);
#endif

@ -0,0 +1,190 @@
#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"
typedef struct fz_archive_s fz_archive;
struct fz_archive_s
{
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_new_archive: Create and initialize an archive struct.
*/
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))
/*
fz_open_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);
/*
fz_open_archive_with_stream: 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);
/*
fz_open_directory: 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);
int fz_is_directory(fz_context *ctx, const char *path);
/*
fz_drop_archive: Release an open archive.
Any allocations for the archive are freed.
*/
void fz_drop_archive(fz_context *ctx, fz_archive *arch);
/*
fz_archive_format: Returns the name of the archive format.
*/
const char *fz_archive_format(fz_context *ctx, fz_archive *arch);
/*
fz_count_archive_entries: Number of entries in archive.
Will always return a value >= 0.
*/
int fz_count_archive_entries(fz_context *ctx, fz_archive *arch);
/*
fz_list_archive_entry: 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.
*/
const char *fz_list_archive_entry(fz_context *ctx, fz_archive *arch, int idx);
/*
fz_has_archive_entry: 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);
/*
fz_open_archive_entry: 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.
*/
fz_stream *fz_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
/*
fz_read_archive_entry: 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.
*/
fz_buffer *fz_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
/*
fz_is_tar_archive: 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);
/*
fz_open_tar_archive: 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);
/*
fz_open_tar_archive_with_stream: 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_is_zip_archive: 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);
/*
fz_open_zip_archive: 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);
/*
fz_open_zip_archive: 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);
typedef struct fz_zip_writer_s fz_zip_writer;
fz_zip_writer *fz_new_zip_writer(fz_context *ctx, const char *filename);
void fz_write_zip_entry(fz_context *ctx, fz_zip_writer *zip, const char *name, fz_buffer *buf, int compress);
void fz_close_zip_writer(fz_context *ctx, fz_zip_writer *zip);
void fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip);
#endif

@ -0,0 +1,80 @@
#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"
/*
fz_band_writer
*/
typedef struct fz_band_writer_s fz_band_writer;
typedef void (fz_write_header_fn)(fz_context *ctx, fz_band_writer *writer, const 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_drop_band_writer_fn)(fz_context *ctx, fz_band_writer *writer);
struct fz_band_writer_s
{
fz_drop_band_writer_fn *drop;
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))
/*
fz_write_header: 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.
pagenum: Page number
cs: Colorspace (NULL for bitmaps)
seps: Separation details (or NULL).
Throws exception if incompatible data format.
*/
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, const fz_colorspace *cs, fz_separations *seps);
/*
fz_write_band: 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);
void fz_drop_band_writer(fz_context *ctx, fz_band_writer *writer);
#endif

@ -0,0 +1,87 @@
/*
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"
typedef enum fz_bidi_direction_e
{
FZ_BIDI_LTR = 0,
FZ_BIDI_RTL = 1,
FZ_BIDI_NEUTRAL = 2
}
fz_bidi_direction;
typedef enum fz_bidi_flags_e
{
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,140 @@
#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.
*/
typedef struct fz_bitmap_s fz_bitmap;
/*
fz_keep_bitmap: Take a reference to a bitmap.
bit: The bitmap to increment the reference for.
Returns bit.
*/
fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit);
/*
fz_drop_bitmap: Drop a reference and free a bitmap.
Decrement the reference count for the bitmap. When no
references remain the pixmap will be freed.
*/
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_s fz_halftone;
/*
fz_new_bitmap_from_pixmap: 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);
/*
fz_new_bitmap_from_pixmap_band: 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);
struct fz_bitmap_s
{
int refs;
int w, h, stride, n;
int xres, yres;
unsigned char *samples;
};
/*
fz_new_bitmap: 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);
/*
fz_bitmap_details: 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);
/*
fz_clear_bitmap: Clear a previously created bitmap.
bit: The bitmap to clear.
*/
void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit);
/*
fz_default_halftone: 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);
/*
fz_keep_halftone: Take an additional reference to a
halftone.
*/
fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half);
/*
fz_drop_halftone: Drop a reference to a halftone. If the
reference count reaches zero, ht will be destroyed.
*/
void fz_drop_halftone(fz_context *ctx, fz_halftone *ht);
#endif

@ -0,0 +1,155 @@
#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.
*/
typedef struct fz_buffer_s fz_buffer;
/*
fz_keep_buffer: Increment the reference count for a buffer.
Returns a pointer to the buffer.
*/
fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf);
/*
fz_drop_buffer: Decrement the reference count for a buffer.
*/
void fz_drop_buffer(fz_context *ctx, fz_buffer *buf);
/*
fz_buffer_storage: 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);
/*
fz_string_from_buffer: 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_new_buffer: Create a new buffer.
capacity: Initial capacity.
Returns pointer to new buffer.
*/
fz_buffer *fz_new_buffer(fz_context *ctx, size_t capacity);
/*
fz_new_buffer_from_data: 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);
/*
fz_new_buffer_from_shared_data: 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);
/*
fz_new_buffer_from_copied_data: 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);
/*
fz_new_buffer_from_base64: 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);
/*
fz_resize_buffer: 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);
/*
fz_grow_buffer: Make some space within a buffer (i.e. ensure that
capacity > size).
*/
void fz_grow_buffer(fz_context *ctx, fz_buffer *buf);
/*
fz_trim_buffer: Trim wasted capacity from a buffer by resizing internal memory.
*/
void fz_trim_buffer(fz_context *ctx, fz_buffer *buf);
/*
fz_append_buffer: Append the contents of source buffer to destination buffer.
*/
void fz_append_buffer(fz_context *ctx, fz_buffer *destination, fz_buffer *source);
/*
fz_append_*: Append data to a buffer.
fz_append_printf: Format and append data to buffer using printf-like formatting (see fz_vsnprintf).
fz_append_pdf_string: Append a string with PDF syntax quotes and escapes.
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);
void fz_append_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...);
void fz_append_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args);
void fz_append_pdf_string(fz_context *ctx, fz_buffer *buffer, const char *text);
/*
fz_terminate_buffer: 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.
*/
void fz_terminate_buffer(fz_context *ctx, fz_buffer *buf);
/*
fz_md5_buffer: Create MD5 digest of buffer contents.
*/
void fz_md5_buffer(fz_context *ctx, fz_buffer *buffer, unsigned char digest[16]);
/*
fz_buffer_extract: 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,115 @@
#ifndef MUPDF_FITZ_COLOR_MANAGEMENT_H
#define MUPDF_FITZ_COLOR_MANAGEMENT_H
#include "mupdf/fitz/colorspace.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/pixmap.h"
/*
MuPDF can either run with or without color management. By default
MuPDF runs without color management. To enable color management,
a color management engine must be given to the context.
The context will then create one 'instance' of this engine per
cloned context. Every instance is tied to the particular context
in which it is created.
Profiles and links can be shared between instances.
*/
/*
fz_cmm_new_instance_fn: Create a new instance of the color
management engine, tied to the given context.
*/
typedef fz_cmm_instance *(fz_cmm_new_instance_fn)(fz_context *ctx);
/*
fz_cmm_drop_instance_fn: Drop a given instance of the color
management engine. No further calls will be made to this
instance.
*/
typedef void (fz_cmm_drop_instance_fn)(fz_cmm_instance *instance);
/*
fz_cmm_transform_pixmap_fn: Transform a pixmap according
to a link.
*/
typedef void (fz_cmm_transform_pixmap_fn)(fz_cmm_instance *ctx, fz_icclink *link, fz_pixmap *dst, fz_pixmap *src);
/*
fz_cmm_transform_color_fn: Transform some color values according
to a link.
*/
typedef void (fz_cmm_transform_color_fn)(fz_cmm_instance *ctx, fz_icclink *link, unsigned short *dst, const unsigned short *src);
/*
fz_cmm_init_link_fn: Create a new link between icc profiles.
*/
typedef void (fz_cmm_init_link_fn)(fz_cmm_instance *ctx, fz_icclink *link, const fz_iccprofile *dst, int dst_extras, const fz_iccprofile *src, int src_extras, const fz_iccprofile *prf, const fz_color_params *rend, int cmm_flags, int num_bytes, int copy_spots);
/*
fz_cmm_fin_link_fn: Drop a link.
*/
typedef void (fz_cmm_fin_link_fn)(fz_cmm_instance *ctx, fz_icclink *link);
/*
fz_cmm_init_profile_fn: Create the cmm specific data for the given
profile. The cmm handle is stored to profile->cmm_handle.
*/
typedef void (fz_cmm_init_profile_fn)(fz_cmm_instance *ctx, fz_iccprofile *profile);
/*
fz_cmm_fin_profile_fn: Drop the cmm specific data for the given
profile.
*/
typedef void (fz_cmm_fin_profile_fn)(fz_cmm_instance *ctx, fz_iccprofile *profile);
/*
Encapsulate details for a given color management engine into a single
structure.
*/
struct fz_cmm_engine_s {
fz_cmm_new_instance_fn *new_instance;
fz_cmm_drop_instance_fn *drop_instance;
fz_cmm_transform_pixmap_fn *transform_pixmap;
fz_cmm_transform_color_fn *transform_color;
fz_cmm_init_link_fn *init_link;
fz_cmm_fin_link_fn *fin_link;
fz_cmm_init_profile_fn *init_profile;
fz_cmm_fin_profile_fn *fin_profile;
int avoid_white_fix_flag;
};
/*
fz_get_cmm_engine: Read details of the current color
management engine. If NULL, we are working without
color management.
*/
const fz_cmm_engine *fz_get_cmm_engine(fz_context *ctx);
/*
fz_set_cmm_engine: Set the color management engine to
be used. This should only ever be called on the "base"
context before cloning it, and before opening any files.
Attempting to change the engine in use once a file has
been opened, or to use different color management engine
for the same file in different threads will lead to
undefined behaviour, including crashing.
Using different ICC engines for different files using
different sets of fz_contexts should theoretically be
possible.
*/
void fz_set_cmm_engine(fz_context *ctx, const fz_cmm_engine *engine);
/*
Currently we only provide a single color management
engine, based on a (modified) LCMS2.
An unmodified LCMS2 should work too, but only when restricted
to a single thread.
*/
extern fz_cmm_engine fz_cmm_engine_lcms;
#endif

@ -0,0 +1,237 @@
#ifndef MUPDF_FITZ_COLORSPACE_H
#define MUPDF_FITZ_COLORSPACE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/store.h"
enum { FZ_MAX_COLORS = 32 };
enum
{
/* Same order as needed by lcms */
FZ_RI_PERCEPTUAL,
FZ_RI_RELATIVE_COLORIMETRIC,
FZ_RI_SATURATION,
FZ_RI_ABSOLUTE_COLORIMETRIC,
};
enum
{
FZ_COLORSPACE_IS_DEVICE = 1,
FZ_COLORSPACE_IS_ICC = 2,
FZ_COLORSPACE_IS_CAL = 4,
FZ_COLORSPACE_LAST_PUBLIC_FLAG = 8,
};
typedef struct fz_color_params_s fz_color_params;
struct fz_color_params_s
{
uint8_t ri;
uint8_t bp;
uint8_t op;
uint8_t opm;
};
int fz_lookup_rendering_intent(const char *name);
char *fz_rendering_intent_name(int ri);
/*
A fz_colorspace object represents an abstract colorspace. While
this should be treated as a black box by callers of the library at
this stage, know that it encapsulates knowledge of how to convert
colors to and from the colorspace, any lookup tables generated, the
number of components in the colorspace etc.
*/
typedef struct fz_colorspace_s fz_colorspace;
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_type fz_colorspace_type(fz_context *ctx, fz_colorspace *cs);
/*
A fz_iccprofile object encapsulates details about the icc profile. It
also includes the profile handle provided by the cmm and as such is used
in the creation of links between color spaces.
*/
typedef struct fz_iccprofile_s fz_iccprofile;
/*
A fz_icclink object encapsulates details about the link between profiles.
*/
typedef struct fz_icclink_s fz_icclink;
/*
Used to communicate any document internal page specific default color spaces.
*/
typedef struct fz_default_colorspaces_s fz_default_colorspaces;
/*
fz_colorspace_is_subtractive: Return true if a colorspace is subtractive.
True for CMYK, Separation and DeviceN colorspaces.
*/
int fz_colorspace_is_subtractive(fz_context *ctx, const fz_colorspace *cs);
/*
fz_colorspace_device_n_has_only_cmyk: Return true if devicen color space
has only colorants from the cmyk set.
*/
int fz_colorspace_device_n_has_only_cmyk(fz_context *ctx, const fz_colorspace *cs);
/*
fz_colorspace_device_n_has_cmyk: Return 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, const fz_colorspace *cs);
/*
Colorspace feature test functions.
*/
int fz_colorspace_is_gray(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_rgb(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_bgr(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_cmyk(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_lab(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_indexed(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_device_n(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_device(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_icc(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_cal(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_device_gray(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_device_cmyk(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_is_lab_icc(fz_context *ctx, const fz_colorspace *cs);
/*
fz_device_gray: Get colorspace representing device specific gray.
*/
fz_colorspace *fz_device_gray(fz_context *ctx);
/*
fz_device_rgb: Get colorspace representing device specific rgb.
*/
fz_colorspace *fz_device_rgb(fz_context *ctx);
/*
fz_device_bgr: Get colorspace representing device specific bgr.
*/
fz_colorspace *fz_device_bgr(fz_context *ctx);
/*
fz_device_cmyk: Get colorspace representing device specific CMYK.
*/
fz_colorspace *fz_device_cmyk(fz_context *ctx);
/*
fz_device_lab: Get colorspace representing device specific LAB.
*/
fz_colorspace *fz_device_lab(fz_context *ctx);
/*
fz_default_color_params: Get default color params for general color conversion.
*/
const fz_color_params *fz_default_color_params(fz_context *ctx);
typedef void (fz_colorspace_convert_fn)(fz_context *ctx, const fz_colorspace *cs, const float *src, float *dst);
typedef void (fz_colorspace_destruct_fn)(fz_context *ctx, fz_colorspace *cs);
typedef fz_colorspace *(fz_colorspace_base_fn)(const fz_colorspace *cs);
typedef void (fz_colorspace_clamp_fn)(const fz_colorspace *cs, const float *src, float *dst);
fz_colorspace *fz_new_colorspace(fz_context *ctx, const char *name, enum fz_colorspace_type type, int flags, int n, fz_colorspace_convert_fn *to_ccs, fz_colorspace_convert_fn *from_ccs, fz_colorspace_base_fn *base, fz_colorspace_clamp_fn *clamp, fz_colorspace_destruct_fn *destruct, void *data, size_t size);
void fz_colorspace_name_colorant(fz_context *ctx, fz_colorspace *cs, int n, const char *name);
const char *fz_colorspace_colorant(fz_context *ctx, const fz_colorspace *cs, int n);
fz_colorspace *fz_new_indexed_colorspace(fz_context *ctx, fz_colorspace *base, int high, unsigned char *lookup);
fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace);
fz_colorspace *fz_keep_colorspace_store_key(fz_context *ctx, fz_colorspace *colorspace);
void fz_drop_colorspace_store_key(fz_context *ctx, fz_colorspace *colorspace);
void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace);
void fz_drop_colorspace_imp(fz_context *ctx, fz_storable *colorspace);
fz_colorspace *fz_colorspace_base(fz_context *ctx, const fz_colorspace *cs);
void fz_set_icc_bgr(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_n(fz_context *ctx, const fz_colorspace *cs);
int fz_colorspace_devicen_n(fz_context *ctx, const fz_colorspace *cs);
const char *fz_colorspace_name(fz_context *ctx, const fz_colorspace *cs);
void fz_clamp_color(fz_context *ctx, const fz_colorspace *cs, const float *in, float *out);
void fz_convert_color(fz_context *ctx, const fz_color_params *params, const fz_colorspace *intcs, const fz_colorspace *dscs, float *dstv, const fz_colorspace *srcs, const float *srcv);
typedef struct fz_color_converter_s fz_color_converter;
/* This structure is public because it allows us to avoid dynamic allocations.
* Callers should only rely on the convert entry - the rest of the structure
* is subject to change without notice.
*/
struct fz_color_converter_s
{
void (*convert)(fz_context *, fz_color_converter *, float *, const float *);
const fz_colorspace *ds;
const fz_colorspace *ss;
const fz_colorspace *is;
void *opaque;
void *link;
int n;
};
void fz_find_color_converter(fz_context *ctx, fz_color_converter *cc, const fz_colorspace *is, const fz_colorspace *ds, const fz_colorspace *ss, const fz_color_params *params);
void fz_drop_color_converter(fz_context *ctx, fz_color_converter *cc);
void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_colorspace *is, fz_colorspace *ds, fz_colorspace *ss, const fz_color_params *params);
void fz_fin_cached_color_converter(fz_context *ctx, fz_color_converter *cc);
/* Public to allow use in icc creation */
typedef struct fz_cal_colorspace_s fz_cal_colorspace;
struct fz_cal_colorspace_s {
float wp[3];
float bp[3];
float gamma[3];
float matrix[9];
int n;
fz_iccprofile *profile;
};
/*
icc methods
*/
fz_colorspace *fz_new_icc_colorspace(fz_context *ctx, const char *name, int num, fz_buffer *buf);
fz_colorspace *fz_new_icc_colorspace_from_file(fz_context *ctx, const char *name, const char *path);
fz_colorspace *fz_new_icc_colorspace_from_stream(fz_context *ctx, const char *name, fz_stream *in);
fz_colorspace *fz_new_cal_colorspace(fz_context *ctx, const char *name, float *wp, float *bp, float *gamma, float *matrix);
fz_buffer *fz_new_icc_data_from_cal_colorspace(fz_context *ctx, fz_cal_colorspace *cal);
fz_buffer *fz_icc_data_from_icc_colorspace(fz_context *ctx, const fz_colorspace *cs);
/* Default cs */
fz_default_colorspaces *fz_new_default_colorspaces(fz_context *ctx);
fz_default_colorspaces* fz_keep_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs);
void fz_drop_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs);
fz_default_colorspaces *fz_clone_default_colorspaces(fz_context *ctx, fz_default_colorspaces *base);
/* Do we want to make fz_default_colorspaces public and get rid of these? */
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);
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);
#endif

@ -0,0 +1,50 @@
#ifndef MUPDF_FITZ_COMPRESS_H
#define MUPDF_FITZ_COMPRESS_H
#include "mupdf/fitz/system.h"
typedef enum
{
FZ_DEFLATE_NONE = 0,
FZ_DEFLATE_BEST_SPEED = 1,
FZ_DEFLATE_BEST = 9,
FZ_DEFLATE_DEFAULT = -1
} fz_deflate_level;
/*
fz_deflate_bound: Returns the upper bound on the
size of flated data of length size.
*/
size_t fz_deflate_bound(fz_context *ctx, size_t size);
/*
fz_deflate: 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);
/*
fz_new_deflated_data: 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);
/*
fz_new_deflated_data_from_buffer: 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);
#endif

@ -0,0 +1,91 @@
#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"
typedef struct fz_compression_params_s fz_compression_params;
typedef struct fz_compressed_buffer_s fz_compressed_buffer;
size_t fz_compressed_buffer_size(fz_compressed_buffer *buffer);
fz_stream *fz_open_compressed_buffer(fz_context *ctx, fz_compressed_buffer *);
fz_stream *fz_open_image_decomp_stream_from_buffer(fz_context *ctx, fz_compressed_buffer *, int *l2factor);
fz_stream *fz_open_image_decomp_stream(fz_context *ctx, fz_stream *, fz_compression_params *, int *l2factor);
int fz_recognize_image_format(fz_context *ctx, unsigned char p[8]);
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_JPEG,
FZ_IMAGE_JPX,
FZ_IMAGE_JXR,
FZ_IMAGE_PNG,
FZ_IMAGE_PNM,
FZ_IMAGE_TIFF,
};
struct fz_compression_params_s
{
int type;
union {
struct {
int color_transform; /* Use -1 for unset */
} jpeg;
struct {
int smask_in_data;
} jpx;
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;
};
struct fz_compressed_buffer_s
{
fz_compression_params params;
fz_buffer *buffer;
};
void fz_drop_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buf);
#endif

@ -0,0 +1,169 @@
#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
/*
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 but GPRF 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_TIFF 1 */
/* #define FZ_ENABLE_HTML 1 */
/* #define FZ_ENABLE_EPUB 1 */
/* #define FZ_ENABLE_GPRF 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 */
/* To skip the CJK font, enable: (this implicitly enables TOFU_CJK_EXT and TOFU_CJK_LANG) */
/* #define TOFU_CJK */
/* 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 ICC profiles, enable: */
/* #define NO_ICC */
/* 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
#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_TIFF
#define FZ_ENABLE_TIFF 1
#endif /* FZ_ENABLE_TIFF */
#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_GPRF
#define FZ_ENABLE_GPRF 0
#endif /* FZ_ENABLE_GPRF */
#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 */
/* 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
#endif /* FZ_CONFIG_H */

@ -0,0 +1,586 @@
#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"
/*
Contexts
*/
typedef struct fz_alloc_context_s fz_alloc_context;
typedef struct fz_error_context_s fz_error_context;
typedef struct fz_error_stack_slot_s fz_error_stack_slot;
typedef struct fz_id_context_s fz_id_context;
typedef struct fz_warn_context_s fz_warn_context;
typedef struct fz_font_context_s fz_font_context;
typedef struct fz_colorspace_context_s fz_colorspace_context;
typedef struct fz_cmm_engine_s fz_cmm_engine;
typedef struct fz_cmm_instance_s fz_cmm_instance;
typedef struct fz_aa_context_s fz_aa_context;
typedef struct fz_style_context_s fz_style_context;
typedef struct fz_locks_context_s fz_locks_context;
typedef struct fz_tuning_context_s fz_tuning_context;
typedef struct fz_store_s fz_store;
typedef struct fz_glyph_cache_s fz_glyph_cache;
typedef struct fz_document_handler_context_s fz_document_handler_context;
typedef struct fz_output_context_s fz_output_context;
typedef struct fz_context_s fz_context;
struct fz_alloc_context_s
{
void *user;
void *(*malloc)(void *, size_t);
void *(*realloc)(void *, void *, size_t);
void (*free)(void *, void *);
};
struct fz_error_stack_slot_s
{
int code;
fz_jmp_buf buffer;
};
struct fz_error_context_s
{
fz_error_stack_slot *top;
fz_error_stack_slot stack[256];
int errcode;
char message[256];
};
void fz_var_imp(void *);
#define fz_var(var) fz_var_imp((void *)&(var))
/*
Exception macro definitions. Just treat these as a black box - pay no
attention to the man behind the curtain.
*/
#define fz_try(ctx) \
{ \
if (fz_push_try(ctx)) { \
if (fz_setjmp((ctx)->error->top->buffer) == 0) do \
#define fz_always(ctx) \
while (0); \
} \
if (ctx->error->top->code < 3) { \
ctx->error->top->code++; \
do \
#define fz_catch(ctx) \
while (0); \
} \
} \
if ((ctx->error->top--)->code > 1)
int fz_push_try(fz_context *ctx);
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);
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);
const char *fz_caught_message(fz_context *ctx);
int fz_caught(fz_context *ctx);
void fz_rethrow_if(fz_context *ctx, int errcode);
enum
{
FZ_ERROR_NONE = 0,
FZ_ERROR_MEMORY = 1,
FZ_ERROR_GENERIC = 2,
FZ_ERROR_SYNTAX = 3,
FZ_ERROR_TRYLATER = 4,
FZ_ERROR_ABORT = 5,
FZ_ERROR_COUNT
};
/*
fz_flush_warnings: 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.
*/
struct fz_locks_context_s
{
void *user;
void (*lock)(void *user, int lock);
void (*unlock)(void *user, int lock);
};
enum {
FZ_LOCK_ALLOC = 0,
FZ_LOCK_FREETYPE,
FZ_LOCK_GLYPHCACHE,
FZ_LOCK_MAX
};
struct fz_context_s
{
void *user;
const fz_alloc_context *alloc;
fz_locks_context locks;
fz_id_context *id;
fz_error_context *error;
fz_warn_context *warn;
fz_font_context *font;
fz_colorspace_context *colorspace;
fz_cmm_instance *cmm_instance;
fz_aa_context *aa;
fz_style_context *style;
fz_store *store;
fz_glyph_cache *glyph_cache;
fz_tuning_context *tuning;
fz_document_handler_context *handler;
fz_output_context *output;
uint16_t seed48[7];
};
/*
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,
};
/*
fz_new_context: 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.
*/
fz_context *fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks, size_t max_store, const char *version);
#define fz_new_context(alloc, locks, max_store) fz_new_context_imp(alloc, locks, max_store, FZ_VERSION)
/*
fz_clone_context: 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);
/*
fz_drop_context: 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.
*/
void fz_drop_context(fz_context *ctx);
/*
fz_set_user_context: 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);
/*
fz_user_context: Read the user field from the context.
*/
void *fz_user_context(fz_context *ctx);
/*
In order to tune MuPDF's behaviour, certain functions can
(optionally) be provided by callers.
*/
/*
fz_tune_image_decode_fn: 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);
/*
fz_tune_image_scale_fn: 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);
/*
fz_tune_image_decode: 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);
/*
fz_tune_image_scale: 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);
/*
fz_aa_level: Get the number of bits of antialiasing we are
using (for graphics). Between 0 and 8.
*/
int fz_aa_level(fz_context *ctx);
/*
fz_set_aa_level: 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);
/*
fz_text_aa_level: Get the number of bits of antialiasing we are
using for text. Between 0 and 8.
*/
int fz_text_aa_level(fz_context *ctx);
/*
fz_set_text_aa_level: 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);
/*
fz_graphics_aa_level: Get the number of bits of antialiasing we are
using for graphics. Between 0 and 8.
*/
int fz_graphics_aa_level(fz_context *ctx);
/*
fz_set_graphics_aa_level: 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);
/*
fz_graphics_min_line_width: 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);
/*
fz_set_graphics_min_line_width: 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);
/*
fz_user_css: Get the user stylesheet source text.
*/
const char *fz_user_css(fz_context *ctx);
/*
fz_set_user_css: Set the user stylesheet source text for use with HTML and EPUB.
*/
void fz_set_user_css(fz_context *ctx, const char *text);
/*
fz_use_document_css: Return whether to respect document styles in HTML and EPUB.
*/
int fz_use_document_css(fz_context *ctx);
/*
fz_set_use_document_css: Toggle whether to respect document styles in HTML and EPUB.
*/
void fz_set_use_document_css(fz_context *ctx, int use);
/*
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.
*/
/*
fz_malloc: Allocate a block of memory (with scavenging)
size: The number of bytes to allocate.
Returns a pointer to the allocated block. May return NULL if size is
0. Throws exception on failure to allocate.
*/
void *fz_malloc(fz_context *ctx, size_t size);
/*
fz_calloc: Allocate a zeroed block of memory (with scavenging)
count: The number of objects to allocate space for.
size: The size (in bytes) of each object.
Returns a pointer to the allocated block. May return NULL if size
and/or count are 0. Throws exception on failure to allocate.
*/
void *fz_calloc(fz_context *ctx, size_t count, size_t size);
/*
fz_malloc_struct: Allocate storage for a structure (with scavenging),
clear it, and (in Memento builds) tag the pointer as belonging to a
struct of this type.
CTX: The context.
STRUCT: The structure type.
Returns a pointer to allocated (and cleared) structure. Throws
exception on failure to allocate.
*/
#define fz_malloc_struct(CTX, STRUCT) \
((STRUCT *)Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT))
/*
fz_malloc_array: Allocate a block of (non zeroed) memory (with
scavenging). Equivalent to fz_calloc without the memory clearing.
count: The number of objects to allocate space for.
size: The size (in bytes) of each object.
Returns a pointer to the allocated block. May return NULL if size
and/or count are 0. Throws exception on failure to allocate.
*/
void *fz_malloc_array(fz_context *ctx, size_t count, size_t size);
/*
fz_resize_array: Resize a block of memory (with scavenging).
p: The existing block to resize
count: The number of objects to resize to.
size: The size (in bytes) of each object.
Returns a pointer to the resized block. May return NULL if size
and/or count are 0. Throws exception on failure to resize (original
block is left unchanged).
*/
void *fz_resize_array(fz_context *ctx, void *p, size_t count, size_t size);
/*
fz_strdup: Duplicate a C string (with scavenging)
s: The string to duplicate.
Returns a pointer to a duplicated string. Throws exception on failure
to allocate.
*/
char *fz_strdup(fz_context *ctx, const char *s);
/*
fz_free: Frees an allocation.
*/
void fz_free(fz_context *ctx, void *p);
/*
fz_malloc_no_throw: Allocate a block of memory (with scavenging)
size: The number of bytes to allocate.
Returns a pointer to the allocated block. May return NULL if size is
0. Returns NULL on failure to allocate.
*/
void *fz_malloc_no_throw(fz_context *ctx, size_t size);
/*
fz_calloc_no_throw: Allocate a zeroed block of memory (with scavenging)
count: The number of objects to allocate space for.
size: The size (in bytes) of each object.
Returns a pointer to the allocated block. May return NULL if size
and/or count are 0. Returns NULL on failure to allocate.
*/
void *fz_calloc_no_throw(fz_context *ctx, size_t count, size_t size);
/*
fz_malloc_array_no_throw: Allocate a block of (non zeroed) memory
(with scavenging). Equivalent to fz_calloc_no_throw without the
memory clearing.
count: The number of objects to allocate space for.
size: The size (in bytes) of each object.
Returns a pointer to the allocated block. May return NULL if size
and/or count are 0. Returns NULL on failure to allocate.
*/
void *fz_malloc_array_no_throw(fz_context *ctx, size_t count, size_t size);
/*
fz_resize_array_no_throw: Resize a block of memory (with scavenging).
p: The existing block to resize
count: The number of objects to resize to.
size: The size (in bytes) of each object.
Returns a pointer to the resized block. May return NULL if size
and/or count are 0. Returns NULL on failure to resize (original
block is left unchanged).
*/
void *fz_resize_array_no_throw(fz_context *ctx, void *p, size_t count, size_t size);
/*
fz_strdup_no_throw: Duplicate a C string (with scavenging)
s: The string to duplicate.
Returns a pointer to a duplicated string. Returns NULL on failure
to allocate.
*/
char *fz_strdup_no_throw(fz_context *ctx, const char *s);
/*
fz_gen_id: Generate an id (guaranteed unique within this family of
contexts).
*/
int fz_gen_id(fz_context *ctx);
struct fz_warn_context_s
{
char message[256];
int count;
};
/* Default allocator */
extern fz_alloc_context fz_alloc_default;
/* Default locks */
extern fz_locks_context fz_locks_default;
/*
Pseudo-random numbers using a linear congruential algorithm and 48-bit
integer arithmetic.
*/
double fz_drand48(fz_context *ctx);
int32_t fz_lrand48(fz_context *ctx);
int32_t fz_mrand48(fz_context *ctx);
double fz_erand48(fz_context *ctx, uint16_t xsubi[3]);
int32_t fz_jrand48(fz_context *ctx, uint16_t xsubi[3]);
int32_t fz_nrand48(fz_context *ctx, uint16_t xsubi[3]);
void fz_lcong48(fz_context *ctx, uint16_t param[7]);
uint16_t *fz_seed48(fz_context *ctx, uint16_t seed16v[3]);
void fz_srand48(fz_context *ctx, int32_t seedval);
/*
fz_memrnd: Fill block with len bytes of pseudo-randomness.
*/
void fz_memrnd(fz_context *ctx, uint8_t *block, int len);
#endif

@ -0,0 +1,126 @@
#ifndef MUPDF_FITZ_CRYPT_H
#define MUPDF_FITZ_CRYPT_H
#include "mupdf/fitz/system.h"
/*
* Basic crypto functions.
* Independent of the rest of fitz.
* For further encapsulation in filters, or not.
*/
/* md5 digests */
typedef struct fz_md5_s fz_md5;
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_md5_s
{
unsigned int state[4];
unsigned int count[2];
unsigned char buffer[64];
};
void fz_md5_init(fz_md5 *state);
void fz_md5_update(fz_md5 *state, const unsigned char *input, size_t inlen);
void fz_md5_final(fz_md5 *state, unsigned char digest[16]);
/* sha-256 digests */
typedef struct fz_sha256_s fz_sha256;
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_sha256_s
{
unsigned int state[8];
unsigned int count[2];
union {
unsigned char u8[64];
unsigned int u32[16];
} buffer;
};
void fz_sha256_init(fz_sha256 *state);
void fz_sha256_update(fz_sha256 *state, const unsigned char *input, size_t inlen);
void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]);
/* sha-512 digests */
typedef struct fz_sha512_s fz_sha512;
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_sha512_s
{
uint64_t state[8];
unsigned int count[2];
union {
unsigned char u8[128];
uint64_t u64[16];
} buffer;
};
void fz_sha512_init(fz_sha512 *state);
void fz_sha512_update(fz_sha512 *state, const unsigned char *input, size_t inlen);
void fz_sha512_final(fz_sha512 *state, unsigned char digest[64]);
/* sha-384 digests */
typedef struct fz_sha512_s fz_sha384;
void fz_sha384_init(fz_sha384 *state);
void fz_sha384_update(fz_sha384 *state, const unsigned char *input, size_t inlen);
void fz_sha384_final(fz_sha384 *state, unsigned char digest[64]);
/* arc4 crypto */
typedef struct fz_arc4_s fz_arc4;
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_arc4_s
{
unsigned x;
unsigned y;
unsigned char state[256];
};
void fz_arc4_init(fz_arc4 *state, const unsigned char *key, size_t len);
void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, size_t len);
/* AES block cipher implementation from XYSSL */
typedef struct fz_aes_s fz_aes;
#define FZ_AES_DECRYPT 0
#define FZ_AES_ENCRYPT 1
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_aes_s
{
int nr; /* number of rounds */
unsigned long *rk; /* AES round keys */
unsigned long buf[68]; /* unaligned data */
};
int fz_aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize );
int fz_aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize );
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,417 @@
#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/colorspace.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_s 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
};
int fz_lookup_blendmode(const char *name);
char *fz_blendmode_name(int blendmode);
typedef struct fz_device_container_stack_s fz_device_container_stack;
struct fz_device_s
{
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, const fz_matrix *, fz_colorspace *, const float *color, float alpha, const fz_color_params *);
void (*stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, const fz_matrix *, fz_colorspace *, const float *color, float alpha, const fz_color_params *);
void (*clip_path)(fz_context *, fz_device *, const fz_path *, int even_odd, const fz_matrix *, const fz_rect *scissor);
void (*clip_stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, const fz_matrix *, const fz_rect *scissor);
void (*fill_text)(fz_context *, fz_device *, const fz_text *, const fz_matrix *, fz_colorspace *, const float *color, float alpha, const fz_color_params *);
void (*stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, const fz_matrix *, fz_colorspace *, const float *color, float alpha, const fz_color_params *);
void (*clip_text)(fz_context *, fz_device *, const fz_text *, const fz_matrix *, const fz_rect *scissor);
void (*clip_stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, const fz_matrix *, const fz_rect *scissor);
void (*ignore_text)(fz_context *, fz_device *, const fz_text *, const fz_matrix *);
void (*fill_shade)(fz_context *, fz_device *, fz_shade *shd, const fz_matrix *ctm, float alpha, const fz_color_params *color_params);
void (*fill_image)(fz_context *, fz_device *, fz_image *img, const fz_matrix *ctm, float alpha, const fz_color_params *color_params);
void (*fill_image_mask)(fz_context *, fz_device *, fz_image *img, const fz_matrix *ctm, fz_colorspace *, const float *color, float alpha, const fz_color_params *color_params);
void (*clip_image_mask)(fz_context *, fz_device *, fz_image *img, const fz_matrix *ctm, const fz_rect *scissor);
void (*pop_clip)(fz_context *, fz_device *);
void (*begin_mask)(fz_context *, fz_device *, const fz_rect *, int luminosity, fz_colorspace *, const float *bc, const fz_color_params *);
void (*end_mask)(fz_context *, fz_device *);
void (*begin_group)(fz_context *, fz_device *, const fz_rect *, 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 *, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const 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 *);
fz_rect d1_rect;
int error_depth;
char errmess[256];
int container_len;
int container_cap;
fz_device_container_stack *container;
};
void fz_fill_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha, const fz_color_params *color_params);
void fz_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha, const fz_color_params *color_params);
void fz_clip_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, const fz_matrix *ctm, const fz_rect *scissor);
void fz_clip_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor);
void fz_fill_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha, const fz_color_params *color_params);
void fz_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha, const fz_color_params *color_params);
void fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor);
void fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor);
void fz_ignore_text(fz_context *ctx, fz_device *dev, const fz_text *text, const 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, const fz_matrix *ctm, float alpha, const fz_color_params *color_params);
void fz_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm, float alpha, const fz_color_params *color_params);
void fz_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha, const fz_color_params *color_params);
void fz_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm, const fz_rect *scissor);
void fz_begin_mask(fz_context *ctx, fz_device *dev, const fz_rect *area, int luminosity, fz_colorspace *colorspace, const float *bc, const 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, const 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, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm);
int fz_begin_tile_id(fz_context *ctx, fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const 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);
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))
/*
fz_close_device: Signal the end of input, and flush any buffered output.
This is NOT called implicitly on fz_drop_device.
*/
void fz_close_device(fz_context *ctx, fz_device *dev);
/*
fz_drop_device: Free a device of any type and its resources.
Don't forget to call fz_close_device before dropping the device,
or you may get incomplete output!
*/
void fz_drop_device(fz_context *ctx, fz_device *dev);
fz_device *fz_keep_device(fz_context *ctx, fz_device *dev);
/*
fz_enable_device_hints : Enable hints in a device.
hints: mask of hints to enable.
*/
void fz_enable_device_hints(fz_context *ctx, fz_device *dev, int hints);
/*
fz_disable_device_hints : Disable hints in a device.
hints: mask of hints to disable.
*/
void fz_disable_device_hints(fz_context *ctx, fz_device *dev, int hints);
/*
Find current scissor region as tracked by the device.
*/
const fz_rect *fz_device_current_scissor(fz_context *ctx, fz_device *dev);
enum
{
/* Hints */
FZ_DONT_INTERPOLATE_IMAGES = 1,
FZ_MAINTAIN_CONTAINER_STACK = 2,
FZ_NO_CACHE = 4,
};
/*
Cookie support - simple communication channel between app/library.
*/
typedef struct fz_cookie_s fz_cookie;
/*
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_ok: If this is set to 1 by the caller, then TRYLATER
errors are swallowed as they occur, setting the 'incomplete' flag.
Rendering continues as much as possible ignoring errors. The caller
is expected to check the 'incomplete' flag at the end to see if the
rendering may be considered final or not.
incomplete: Initially should be set to 0. Will be set to non-zero
if a TRYLATER error is thrown during rendering and the incomplete_ok
flag is set.
*/
struct fz_cookie_s
{
int abort;
int progress;
int progress_max; /* -1 for unknown */
int errors;
int incomplete_ok;
int incomplete;
};
/*
fz_new_trace_device: Create a device to print a debug trace of all device calls.
*/
fz_device *fz_new_trace_device(fz_context *ctx, fz_output *out);
/*
fz_new_bbox_device: 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);
/*
fz_new_test_device: 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
};
/*
fz_new_draw_device: 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, const fz_matrix *transform, fz_pixmap *dest);
/*
fz_new_draw_device_with_bbox: 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, const fz_matrix *transform, fz_pixmap *dest, const fz_irect *clip);
/*
fz_new_draw_device_with_proof: 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, const fz_matrix *transform, fz_pixmap *dest, fz_colorspace *proof_cs);
/*
fz_new_draw_device_with_bbox_proof: 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, const fz_matrix *transform, fz_pixmap *dest, const fz_irect *clip, fz_colorspace *cs);
fz_device *fz_new_draw_device_type3(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest);
/*
struct fz_draw_options: Options for creating a pixmap and draw device.
*/
typedef struct fz_draw_options_s fz_draw_options;
struct fz_draw_options_s
{
int rotate;
int x_resolution;
int y_resolution;
int width;
int height;
fz_colorspace *colorspace;
int alpha;
int graphics;
int text;
};
extern const char *fz_draw_options_usage;
/*
fz_parse_draw_options: 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);
/*
fz_new_draw_device_with_options: 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, const fz_rect *mediabox, fz_pixmap **pixmap);
#endif

@ -0,0 +1,115 @@
#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_s fz_display_list;
/*
fz_new_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, const fz_rect *mediabox);
/*
fz_new_list_device: 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 ownership of.
*/
fz_device *fz_new_list_device(fz_context *ctx, fz_display_list *list);
/*
fz_run_display_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.
dev: Device obtained from fz_new_*_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.
area: 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, const fz_matrix *ctm, const fz_rect *area, fz_cookie *cookie);
/*
fz_keep_display_list: Keep a reference to a display list.
*/
fz_display_list *fz_keep_display_list(fz_context *ctx, fz_display_list *list);
/*
fz_drop_display_list: Drop a reference to a display list, freeing it
if the reference count reaches zero.
*/
void fz_drop_display_list(fz_context *ctx, fz_display_list *list);
/*
fz_bound_display_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, fz_rect *bounds);
/*
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

@ -0,0 +1,644 @@
#ifndef MUPDF_FITZ_DOCUMENT_H
#define MUPDF_FITZ_DOCUMENT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/device.h"
#include "mupdf/fitz/transition.h"
#include "mupdf/fitz/link.h"
#include "mupdf/fitz/outline.h"
#include "mupdf/fitz/separation.h"
/*
Document interface
*/
typedef struct fz_document_s fz_document;
typedef struct fz_document_handler_s fz_document_handler;
typedef struct fz_page_s fz_page;
typedef struct fz_annot_s fz_annot;
typedef intptr_t fz_bookmark;
typedef enum
{
FZ_PERMISSION_PRINT = 'p',
FZ_PERMISSION_COPY = 'c',
FZ_PERMISSION_EDIT = 'e',
FZ_PERMISSION_ANNOTATE = 'n',
}
fz_permission;
/*
fz_document_drop_fn: Type for a function to be called when
the reference count for the fz_document drops to 0. The
implementation should release any resources held by the
document. The actual document pointer will be freed by the
caller.
*/
typedef void (fz_document_drop_fn)(fz_context *ctx, fz_document *doc);
/*
fz_document_needs_password_fn: Type for a function to be
called to enquire whether the document needs a password
or not. See fz_needs_password for more information.
*/
typedef int (fz_document_needs_password_fn)(fz_context *ctx, fz_document *doc);
/*
fz_document_authenticate_password_fn: Type for a function to be
called to attempt to authenticate a password. See
fz_authenticate_password for more information.
*/
typedef int (fz_document_authenticate_password_fn)(fz_context *ctx, fz_document *doc, const char *password);
/*
fz_document_has_permission_fn: Type for a function to be
called to see if a document grants a certain permission. See
fz_document_has_permission for more information.
*/
typedef int (fz_document_has_permission_fn)(fz_context *ctx, fz_document *doc, fz_permission permission);
/*
fz_document_load_outline_fn: Type for a function to be called to
load the outlines for a document. See fz_document_load_outline
for more information.
*/
typedef fz_outline *(fz_document_load_outline_fn)(fz_context *ctx, fz_document *doc);
/*
fz_document_layout_fn: Type for a function to be called to lay
out a document. See fz_layout_document for more information.
*/
typedef void (fz_document_layout_fn)(fz_context *ctx, fz_document *doc, float w, float h, float em);
/*
fz_document_resolve_link_fn: Type for a function to be called to
resolve an internal link to a page number. See fz_resolve_link
for more information.
*/
typedef int (fz_document_resolve_link_fn)(fz_context *ctx, fz_document *doc, const char *uri, float *xp, float *yp);
/*
fz_document_count_pages_fn: Type for a function to be called to
count the number of pages in a document. See fz_count_pages for
more information.
*/
typedef int (fz_document_count_pages_fn)(fz_context *ctx, fz_document *doc);
/*
fz_document_load_page_fn: Type for a function to load a given
page from a document. See fz_load_page for more information.
*/
typedef fz_page *(fz_document_load_page_fn)(fz_context *ctx, fz_document *doc, int number);
/*
fz_document_lookup_metadata_fn: Type for a function to query
a documents metadata. See fz_lookup_metadata for more
information.
*/
typedef int (fz_document_lookup_metadata_fn)(fz_context *ctx, fz_document *doc, const char *key, char *buf, int size);
/*
fz_document_output_intent_fn: Return output intent color space if it exists
*/
typedef fz_colorspace* (fz_document_output_intent_fn)(fz_context *ctx, fz_document *doc);
/*
fz_document_make_bookmark_fn: Type for a function to make
a bookmark. See fz_make_bookmark for more information.
*/
typedef fz_bookmark (fz_document_make_bookmark_fn)(fz_context *ctx, fz_document *doc, int page);
/*
fz_document_lookup_bookmark_fn: Type for a function to lookup
a bookmark. See fz_lookup_bookmark for more information.
*/
typedef int (fz_document_lookup_bookmark_fn)(fz_context *ctx, fz_document *doc, fz_bookmark mark);
/*
fz_page_drop_page_fn: Type for a function to release all the
resources held by a page. Called automatically when the
reference count for that page reaches zero.
*/
typedef void (fz_page_drop_page_fn)(fz_context *ctx, fz_page *page);
/*
fz_page_bound_page_fn: Type for a function to return the
bounding box of a page. See fz_bound_page for more
information.
*/
typedef fz_rect *(fz_page_bound_page_fn)(fz_context *ctx, fz_page *page, fz_rect *);
/*
fz_page_run_page_contents_fn: Type for a function to run the
contents of a page. See fz_run_page_contents for more
information.
*/
typedef void (fz_page_run_page_contents_fn)(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie);
/*
fz_page_load_links_fn: Type for a function to load the links
from a page. See fz_load_links for more information.
*/
typedef fz_link *(fz_page_load_links_fn)(fz_context *ctx, fz_page *page);
/*
fz_page_first_annot_fn: Type for a function to load the
annotations from a page. See fz_first_annot for more
information.
*/
typedef fz_annot *(fz_page_first_annot_fn)(fz_context *ctx, fz_page *page);
/*
fz_page_page_presentation_fn: Type for a function to
obtain the details of how this page should be presented when
in presentation mode. See fz_page_presentation for more
information.
*/
typedef fz_transition *(fz_page_page_presentation_fn)(fz_context *ctx, fz_page *page, fz_transition *transition, float *duration);
/*
fz_page_control_separation: Type for a function to enable/
disable separations on a page. See fz_control_separation for
more information.
*/
typedef void (fz_page_control_separation_fn)(fz_context *ctx, fz_page *page, int separation, int disable);
/*
fz_page_separation_disabled_fn: Type for a function to detect
whether a given separation is enabled or disabled on a page.
See FZ_SEPARATION_DISABLED for more information.
*/
typedef int (fz_page_separation_disabled_fn)(fz_context *ctx, fz_page *page, int separation);
/*
fz_page_separations_fn: Type for a function to retrieve
details of separations on a page. See fz_get_separations
for more information.
*/
typedef fz_separations *(fz_page_separations_fn)(fz_context *ctx, fz_page *page);
/*
fz_page_uses_overprint_fn: Type for a function to retrieve
whether or not a given page uses overprint.
*/
typedef int (fz_page_uses_overprint_fn)(fz_context *ctx, fz_page *page);
typedef void (fz_annot_drop_fn)(fz_context *ctx, fz_annot *annot);
typedef fz_annot *(fz_annot_next_fn)(fz_context *ctx, fz_annot *annot);
typedef fz_rect *(fz_annot_bound_fn)(fz_context *ctx, fz_annot *annot, fz_rect *rect);
typedef void (fz_annot_run_fn)(fz_context *ctx, fz_annot *annot, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie);
/*
Structure definition is public so other classes can
derive from it. Do not access the members directly.
*/
struct fz_annot_s
{
int refs;
fz_annot_drop_fn *drop_annot;
fz_annot_bound_fn *bound_annot;
fz_annot_run_fn *run_annot;
fz_annot_next_fn *next_annot;
};
/*
Structure definition is public so other classes can
derive from it. Do not access the members directly.
*/
struct fz_page_s
{
int refs;
fz_page_drop_page_fn *drop_page;
fz_page_bound_page_fn *bound_page;
fz_page_run_page_contents_fn *run_page_contents;
fz_page_load_links_fn *load_links;
fz_page_first_annot_fn *first_annot;
fz_page_page_presentation_fn *page_presentation;
fz_page_control_separation_fn *control_separation;
fz_page_separation_disabled_fn *separation_disabled;
fz_page_separations_fn *separations;
fz_page_uses_overprint_fn *overprint;
};
/*
Structure definition is public so other classes can
derive from it. Callers shoud not access the members
directly, though implementations will need initialize
functions directly.
*/
struct fz_document_s
{
int refs;
fz_document_drop_fn *drop_document;
fz_document_needs_password_fn *needs_password;
fz_document_authenticate_password_fn *authenticate_password;
fz_document_has_permission_fn *has_permission;
fz_document_load_outline_fn *load_outline;
fz_document_layout_fn *layout;
fz_document_make_bookmark_fn *make_bookmark;
fz_document_lookup_bookmark_fn *lookup_bookmark;
fz_document_resolve_link_fn *resolve_link;
fz_document_count_pages_fn *count_pages;
fz_document_load_page_fn *load_page;
fz_document_lookup_metadata_fn *lookup_metadata;
fz_document_output_intent_fn *get_output_intent;
int did_layout;
int is_reflowable;
};
/*
fz_document_open_fn: Function type to open a document from a
file.
filename: file to open
Pointer to opened document. Throws exception in case of error.
*/
typedef fz_document *(fz_document_open_fn)(fz_context *ctx, const char *filename);
/*
fz_document_open_with_stream_fn: Function type to open a
document from a file.
stream: fz_stream to read document data from. Must be
seekable for formats that require it.
Pointer to opened document. Throws exception in case of error.
*/
typedef fz_document *(fz_document_open_with_stream_fn)(fz_context *ctx, fz_stream *stream);
/*
fz_document_recognize_fn: Recognize a document type from
a magic string.
magic: string to recognise - typically a filename or mime
type.
Returns a number between 0 (not recognized) and 100
(fully recognized) based on how certain the recognizer
is that this is of the required type.
*/
typedef int (fz_document_recognize_fn)(fz_context *ctx, const char *magic);
struct fz_document_handler_s
{
fz_document_recognize_fn *recognize;
fz_document_open_fn *open;
fz_document_open_with_stream_fn *open_with_stream;
const char **extensions;
const char **mimetypes;
};
/*
fz_register_document_handler: Register a handler
for a document type.
handler: The handler to register.
*/
void fz_register_document_handler(fz_context *ctx, const fz_document_handler *handler);
/*
fz_register_document_handler: Register handlers
for all the standard document types supported in
this build.
*/
void fz_register_document_handlers(fz_context *ctx);
/*
fz_recognize_document: Given a magic find a document
handler that can handle a document of this type.
magic: Can be a file extension (including initial period) or
a mimetype.
*/
const fz_document_handler *fz_recognize_document(fz_context *ctx, const char *magic);
/*
fz_open_document: Open a PDF, XPS or CBZ document.
Open a document file and read its basic structure so pages and
objects can be located. MuPDF will try to repair broken
documents (without actually changing the file contents).
The returned fz_document is used when calling most other
document related functions.
filename: a path to a file as it would be given to open(2).
*/
fz_document *fz_open_document(fz_context *ctx, const char *filename);
/*
fz_open_document_with_stream: Open a PDF, XPS or CBZ document.
Open a document using the specified stream object rather than
opening a file on disk.
magic: a string used to detect document type; either a file name or mime-type.
*/
fz_document *fz_open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream);
/*
fz_new_document: Create and initialize a document struct.
*/
void *fz_new_document_of_size(fz_context *ctx, int size);
#define fz_new_derived_document(C,M) ((M*)Memento_label(fz_new_document_of_size(C, sizeof(M)), #M))
/*
fz_keep_document: Keep a reference to an open document.
*/
fz_document *fz_keep_document(fz_context *ctx, fz_document *doc);
/*
fz_drop_document: Release an open document.
The resource store in the context associated with fz_document
is emptied, and any allocations for the document are freed when
the last reference is dropped.
*/
void fz_drop_document(fz_context *ctx, fz_document *doc);
/*
fz_needs_password: Check if a document is encrypted with a
non-blank password.
*/
int fz_needs_password(fz_context *ctx, fz_document *doc);
/*
fz_authenticate_password: Test if the given password can
decrypt the document.
password: The password string to be checked. Some document
specifications do not specify any particular text encoding, so
neither do we.
Returns 0 for failure to authenticate, non-zero for success.
For PDF documents, further information can be given by examining
the bits in the return code.
Bit 0 => No password required
Bit 1 => User password authenticated
Bit 2 => Owner password authenticated
*/
int fz_authenticate_password(fz_context *ctx, fz_document *doc, const char *password);
/*
fz_load_outline: Load the hierarchical document outline.
Should be freed by fz_drop_outline.
*/
fz_outline *fz_load_outline(fz_context *ctx, fz_document *doc);
/*
fz_is_document_reflowable: Is the document reflowable.
Returns 1 to indicate reflowable documents, otherwise 0.
*/
int fz_is_document_reflowable(fz_context *ctx, fz_document *doc);
/*
fz_layout_document: Layout reflowable document types.
w, h: Page size in points.
em: Default font size in points.
*/
void fz_layout_document(fz_context *ctx, fz_document *doc, float w, float h, float em);
/*
Create a bookmark for the given page, which can be used to find the
same location after the document has been laid out with different
parameters.
*/
fz_bookmark fz_make_bookmark(fz_context *ctx, fz_document *doc, int page);
/*
Find a bookmark and return its page number.
*/
int fz_lookup_bookmark(fz_context *ctx, fz_document *doc, fz_bookmark mark);
/*
fz_count_pages: Return the number of pages in document
May return 0 for documents with no pages.
*/
int fz_count_pages(fz_context *ctx, fz_document *doc);
/*
fz_resolve_link: Resolve an internal link to a page number.
xp, yp: Pointer to store coordinate of destination on the page.
Returns -1 if the URI cannot be resolved.
*/
int fz_resolve_link(fz_context *ctx, fz_document *doc, const char *uri, float *xp, float *yp);
/*
fz_load_page: Load a page.
After fz_load_page is it possible to retrieve the size of the
page using fz_bound_page, or to render the page using
fz_run_page_*. Free the page by calling fz_drop_page.
number: page number, 0 is the first page of the document.
*/
fz_page *fz_load_page(fz_context *ctx, fz_document *doc, int number);
/*
fz_load_links: Load the list of links for a page.
Returns a linked list of all the links on the page, each with
its clickable region and link destination. Each link is
reference counted so drop and free the list of links by
calling fz_drop_link on the pointer return from fz_load_links.
page: Page obtained from fz_load_page.
*/
fz_link *fz_load_links(fz_context *ctx, fz_page *page);
/*
fz_new_page_of_size: Create and initialize a page struct.
*/
fz_page *fz_new_page_of_size(fz_context *ctx, int size);
#define fz_new_derived_page(CTX,TYPE) \
((TYPE *)Memento_label(fz_new_page_of_size(CTX,sizeof(TYPE)),#TYPE))
/*
fz_bound_page: Determine the size of a page at 72 dpi.
*/
fz_rect *fz_bound_page(fz_context *ctx, fz_page *page, fz_rect *rect);
/*
fz_run_page: Run a page through a device.
page: Page obtained from fz_load_page.
dev: Device obtained from fz_new_*_device.
transform: Transform to apply to page. May include for example
scaling and rotation, see fz_scale, fz_rotate and fz_concat.
Set to fz_identity if no transformation is desired.
cookie: Communication mechanism between caller and library
rendering the page. Intended for multi-threaded applications,
while single-threaded applications set cookie to NULL. The
caller may abort an ongoing rendering of a page. Cookie also
communicates progress information back to the caller. The
fields inside cookie are continually updated while the page is
rendering.
*/
void fz_run_page(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie);
/*
fz_run_page_contents: Run a page through a device. Just the main
page content, without the annotations, if any.
page: Page obtained from fz_load_page.
dev: Device obtained from fz_new_*_device.
transform: Transform to apply to page. May include for example
scaling and rotation, see fz_scale, fz_rotate and fz_concat.
Set to fz_identity if no transformation is desired.
cookie: Communication mechanism between caller and library
rendering the page. Intended for multi-threaded applications,
while single-threaded applications set cookie to NULL. The
caller may abort an ongoing rendering of a page. Cookie also
communicates progress information back to the caller. The
fields inside cookie are continually updated while the page is
rendering.
*/
void fz_run_page_contents(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie);
/*
fz_run_annot: Run an annotation through a device.
page: Page obtained from fz_load_page.
annot: an annotation.
dev: Device obtained from fz_new_*_device.
transform: Transform to apply to page. May include for example
scaling and rotation, see fz_scale, fz_rotate and fz_concat.
Set to fz_identity if no transformation is desired.
cookie: Communication mechanism between caller and library
rendering the page. Intended for multi-threaded applications,
while single-threaded applications set cookie to NULL. The
caller may abort an ongoing rendering of a page. Cookie also
communicates progress information back to the caller. The
fields inside cookie are continually updated while the page is
rendering.
*/
void fz_run_annot(fz_context *ctx, fz_annot *annot, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie);
/*
fz_keep_page: Keep a reference to a loaded page.
*/
fz_page *fz_keep_page(fz_context *ctx, fz_page *page);
/*
fz_drop_page: Free a loaded page.
*/
void fz_drop_page(fz_context *ctx, fz_page *page);
/*
fz_page_presentation: Get the presentation details for a given page.
transition: A pointer to a transition struct to fill out.
duration: A pointer to a place to set the page duration in seconds.
Will be set to 0 if no transition is specified for the page.
Returns: a pointer to the transition structure, or NULL if there is no
transition specified for the page.
*/
fz_transition *fz_page_presentation(fz_context *ctx, fz_page *page, fz_transition *transition, float *duration);
/*
fz_has_permission: Check permission flags on document.
*/
int fz_has_permission(fz_context *ctx, fz_document *doc, fz_permission p);
/*
fz_lookup_metadata: Retrieve document meta data strings.
doc: The document to query.
key: Which meta data key to retrieve...
Basic information:
'format' -- Document format and version.
'encryption' -- Description of the encryption used.
From the document information dictionary:
'info:Title'
'info:Author'
'info:Subject'
'info:Keywords'
'info:Creator'
'info:Producer'
'info:CreationDate'
'info:ModDate'
buf: The buffer to hold the results (a nul-terminated UTF-8 string).
size: Size of 'buf'.
Returns the size of the output string (may be larger than 'size' if
the output was truncated), or -1 if the key is not recognized or found.
*/
int fz_lookup_metadata(fz_context *ctx, fz_document *doc, const char *key, char *buf, int size);
#define FZ_META_FORMAT "format"
#define FZ_META_ENCRYPTION "encryption"
#define FZ_META_INFO_AUTHOR "info:Author"
#define FZ_META_INFO_TITLE "info:Title"
/*
Find the output intent colorspace if the document has defined one.
*/
fz_colorspace *fz_document_output_intent(fz_context *ctx, fz_document *doc);
/*
fz_page_separations: Get the separations details for a page.
This will be NULL, unless the format specifically supports
separations (such as gproof, or PDF files). May be NULL even
so, if there are no separations on a page.
Returns a reference that must be dropped.
*/
fz_separations *fz_page_separations(fz_context *ctx, fz_page *page);
/*
fz_page_uses_overprint: Find out whether a given page requests
overprint.
*/
int fz_page_uses_overprint(fz_context *ctx, fz_page *page);
/*
fz_save_gproof: Given a currently open document, create a
gproof skeleton file from that document.
doc_filename: The name of the currently opened document file.
doc: The currently opened document.
filename: The filename of the desired gproof file.
res: The resolution at which proofing should be done.
print_profile: The filename of the ICC profile for the printer we are proofing
display_profile: The filename of the ICC profile for our display device
*/
void fz_save_gproof(fz_context *ctx, const char *doc_filename, fz_document *doc, const char *filename, int res,
const char *print_profile, const char *display_profile);
#endif

@ -0,0 +1,46 @@
#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_s fz_jbig2_globals;
typedef struct
{
int64_t offset;
int len;
} fz_range;
fz_stream *fz_open_copy(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_null_n(fz_context *ctx, fz_stream *chain, fz_range *ranges, int nranges);
fz_stream *fz_open_null(fz_context *ctx, fz_stream *chain, int len, int64_t offset);
fz_stream *fz_open_concat(fz_context *ctx, int max, int pad);
void fz_concat_push_drop(fz_context *ctx, fz_stream *concat, fz_stream *chain); /* Ownership of chain is passed in */
fz_stream *fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
fz_stream *fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
fz_stream *fz_open_a85d(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_ahxd(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_rld(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int l2factor, fz_stream *jpegtables);
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);
fz_stream *fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits);
fz_stream *fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits, int reverse_bits, int old_tiff);
fz_stream *fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, int colors, int bpc);
fz_stream *fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals);
fz_jbig2_globals *fz_load_jbig2_globals(fz_context *ctx, fz_buffer *buf);
void fz_drop_jbig2_globals_imp(fz_context *ctx, fz_storable *globals);
/* Extra filters for tiff */
fz_stream *fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w);
fz_stream *fz_open_sgilog24(fz_context *ctx, fz_stream *chain, int w);
fz_stream *fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w);
fz_stream *fz_open_thunder(fz_context *ctx, fz_stream *chain, int w);
#endif

@ -0,0 +1,631 @@
#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"
/* forward declaration for circular dependency */
struct fz_device_s;
/*
An abstract font handle.
*/
typedef struct fz_font_s fz_font;
/*
* Fonts come in two variants:
* Regular fonts are handled by FreeType.
* Type 3 fonts have callbacks to the interpreter.
*/
/*
fz_font_ft_face: 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);
/*
fz_font_t3_procs: 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);
/*
ft_error_string: 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);
/* common CJK font collections */
enum { FZ_ADOBE_CNS_1, FZ_ADOBE_GB_1, FZ_ADOBE_JAPAN_1, FZ_ADOBE_KOREA_1 };
/*
fz_font_flags_t: 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;
} fz_font_flags_t;
/*
fz_font_flags: 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);
/*
fz_shaper_data_t: 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;
/*
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);
/*
fz_font_name: 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);
/*
fz_font_is_bold: Returns true if the font is bold.
*/
int fz_font_is_bold(fz_context *ctx, fz_font *font);
/*
fz_font_is_italic: Returns true if the font is italic.
*/
int fz_font_is_italic(fz_context *ctx, fz_font *font);
/*
fz_font_is_serif: Returns true if the font is serif.
*/
int fz_font_is_serif(fz_context *ctx, fz_font *font);
/*
fz_font_is_monospaced: Returns true if the font is monospaced.
*/
int fz_font_is_monospaced(fz_context *ctx, fz_font *font);
/*
fz_font_bbox: Retrieve a pointer to the font bbox.
font: The font to query.
Returns a pointer to the font bbox (or NULL if the
font is NULL).
*/
fz_rect *fz_font_bbox(fz_context *ctx, fz_font *font);
/*
fz_load_system_font_fn: 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);
/*
fz_load_system_cjk_font_fn: Type for user supplied cjk font loading hook.
name: The name of the font to load.
ros: The registry from which to load the font (e.g. FZ_ADOBE_KOREA_1)
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 ros, int serif);
/*
fz_load_system_fallback_font_fn: 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);
/*
fz_install_load_system_font_fn: 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);
/* fz_load_*_font returns NULL if no font could be loaded (also on error) */
/*
fz_load_system_font: 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);
/*
fz_load_system_cjk_font: Attempt to load a given font from
the system.
name: The name of the desired font.
ros: The registry to load the font from (e.g. FZ_ADOBE_KOREA_1)
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 ros, int serif);
/*
fz_lookup_builtin_font: 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);
/*
fz_lookup_base14_font: 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);
/* ToDo: Share fz_lookup_builtin_font and fz_lookup_icc? Check with Tor */
/*
fz_lookup_icc: Search for icc profile.
name: The name of the profile desired (gray-icc, rgb-icc, cmyk-icc or lab-icc).
len: Pointer to a place to receive the length of the discovered.
Returns a pointer to the icc file data, or NULL if not present.
*/
const unsigned char *fz_lookup_icc(fz_context *ctx, const char *name, size_t *len);
/*
fz_lookup_cjk_font: 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.
registry: The desired registry to lookup in (e.g.
FZ_ADOBE_KOREA_1).
serif: 1 if serif desired, 0 otherwise.
wmode: 1 for vertical mode, 0 for horizontal.
len: Pointer to a place to receive the length of the discovered
font buffer.
index: Pointer to a place to store the 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(fz_context *ctx, int registry, int serif, int wmode, int *len, int *index);
/*
fz_lookup_noto_font: 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).
serif: 1 if serif 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_noto_font(fz_context *ctx, int script, int lang, int serif, int *len);
/*
fz_lookup_noto_symbol_font: Search the builtin noto fonts
for a symbol font. Whether a font is present or not will
depend on the configuration in which MuPDF is built.
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_symbol_font(fz_context *ctx, int *len);
/*
fz_lookup_noto_emoji_font: Search the builtin noto fonts
for an emoji font. Whether a font is present or not will
depend on the configuration in which MuPDF is built.
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_emoji_font(fz_context *ctx, int *len);
/*
fz_load_fallback_font: 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);
/*
fz_load_fallback_symbol_font: Try to load a fallback
symbol font. Whether a font is present or not will
depend on the configuration in which MuPDF is built.
Returns a new font handle, or NULL if not available.
*/
fz_font *fz_load_fallback_symbol_font(fz_context *ctx);
/*
fz_load_fallback_emoji_font: Try to load a fallback
emoji font. Whether a font is present or not will
depend on the configuration in which MuPDF is built.
Returns a new font handle, or NULL if not available.
*/
fz_font *fz_load_fallback_emoji_font(fz_context *ctx);
/*
fz_new_type3_font: 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, const fz_matrix *matrix);
/*
fz_new_font_from_memory: Create a new font from a font
file in memory.
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);
/*
fz_new_font_from_buffer: Create a new font from a font
file in a fz_buffer.
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);
/*
fz_new_font_from_file: Create a new font from a font
file.
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 registry, int serif, int wmode);
fz_font *fz_new_builtin_font(fz_context *ctx, const char *name, int is_bold, int is_italic);
/*
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);
/*
fz_set_font_bbox: 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);
/*
fz_bound_glyph: 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.
r: Pointer to a fz_rect to use for storage.
Returns r, after filling it in with the bounds of the given glyph.
*/
fz_rect *fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_rect *r);
/*
fz_glyph_cacheable: 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);
/*
fz_run_t3_glyph: 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, const fz_matrix *trm, struct fz_device_s *dev);
/*
fz_decouple_type3_font: Internal function to remove the
references to a document held by a Type3 font. This is
called during document destruction to ensure that Type3
fonts clean up properly.
Without this call being made, Type3 fonts can be left
holding pdf_obj references for the sake of interpretation
operations that will never come. These references
cannot be freed after the document, hence this function
forces them to be freed earlier in the process.
font: The font to decouple.
t3doc: The document to which the font may refer.
*/
void fz_decouple_type3_font(fz_context *ctx, fz_font *font, void *t3doc);
/*
fz_advance_glyph: 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);
/*
fz_encode_character: 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);
/*
fz_encode_character_with_fallback: 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);
/*
fz_get_glyph_name: 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);
/*
Get font ascender and descender values.
*/
float fz_font_ascender(fz_context *ctx, fz_font *font);
float fz_font_descender(fz_context *ctx, fz_font *font);
/*
Internal functions for our Harfbuzz integration
to work around the lack of thread safety.
*/
/*
fz_hb_lock: Lock against Harfbuzz being called
simultaneously in several threads. This reuses
FZ_LOCK_FREETYPE.
*/
void fz_hb_lock(fz_context *ctx);
/*
fz_hb_unlock: Unlock after a Harfbuzz call. This reuses
FZ_LOCK_FREETYPE.
*/
void fz_hb_unlock(fz_context *ctx);
#endif

@ -0,0 +1,640 @@
#ifndef MUPDF_FITZ_MATH_H
#define MUPDF_FITZ_MATH_H
#include "mupdf/fitz/system.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;
}
/*
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);
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 inlines 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 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 int64_t fz_maxi64(int64_t a, int64_t b)
{
return (a > b ? a : b);
}
static inline float fz_clamp(float f, float min, float max)
{
return (f > min ? (f < max ? f : max) : min);
}
static inline int fz_clampi(int i, int min, int max)
{
return (i > min ? (i < max ? i : max) : min);
}
static inline double fz_clampd(double d, double min, double max)
{
return (d > min ? (d < max ? d : max) : min);
}
static inline void *fz_clampp(void *p, void *min, void *max)
{
return (p > min ? (p < max ? p : max) : min);
}
#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 fz_point_s fz_point;
struct fz_point_s
{
float x, y;
};
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.
The relationship between the coordinates are that x0 <= x1 and
y0 <= y1 in all cases except for infinite rectangles. The area
of a rectangle is defined as (x1 - x0) * (y1 - y0). If either
x0 > x1 or y0 > y1 is true for a given rectangle then it is
defined to be infinite.
To check for empty or infinite rectangles use fz_is_empty_rect
and fz_is_infinite_rect.
x0, y0: The top left corner.
x1, y1: The bottom right corner.
*/
typedef struct fz_rect_s fz_rect;
struct fz_rect_s
{
float x0, y0;
float x1, y1;
};
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_rect_min: get the minimum point from a rectangle as a fz_point.
*/
static inline fz_point *fz_rect_min(fz_rect *f)
{
return (fz_point *)&f->x0;
}
/*
fz_rect_max: get the maximum point from a rectangle as a fz_point.
*/
static inline fz_point *fz_rect_max(fz_rect *f)
{
return (fz_point *)&f->x1;
}
/*
fz_irect is a rectangle using integers instead of floats.
It's used in the draw device and for pixmap dimensions.
*/
typedef struct fz_irect_s fz_irect;
struct fz_irect_s
{
int x0, y0;
int x1, y1;
};
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).
*/
extern const fz_rect fz_unit_rect;
/*
An empty rectangle with an area equal to zero.
Both the top left and bottom right corner are at (0, 0).
*/
extern const fz_rect fz_empty_rect;
extern const fz_irect fz_empty_irect;
/*
An infinite rectangle with negative area.
The corner (x0, y0) is at (1, 1) while the corner (x1, y1) is
at (-1, -1).
*/
extern const fz_rect fz_infinite_rect;
extern const fz_irect fz_infinite_irect;
/*
fz_is_empty_rect: Check if rectangle is empty.
An empty rectangle is defined as one whose area is zero.
*/
static inline int
fz_is_empty_rect(const fz_rect *r)
{
return ((r)->x0 == (r)->x1 || (r)->y0 == (r)->y1);
}
static inline int
fz_is_empty_irect(const fz_irect *r)
{
return ((r)->x0 == (r)->x1 || (r)->y0 == (r)->y1);
}
/*
fz_is_infinite_rect: Check if rectangle is infinite.
An infinite rectangle is defined as one where either of the
two relationships between corner coordinates are not true.
*/
static inline int
fz_is_infinite_rect(const fz_rect *r)
{
return ((r)->x0 > (r)->x1 || (r)->y0 > (r)->y1);
}
/*
fz_is_infinite_irect: Check if an integer rectangle
is infinite.
An infinite rectangle is defined as one where either of the
two relationships between corner coordinates are not true.
*/
static inline int
fz_is_infinite_irect(const fz_irect *r)
{
return ((r)->x0 > (r)->x1 || (r)->y0 > (r)->y1);
}
/*
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 fz_matrix_s fz_matrix;
struct fz_matrix_s
{
float a, b, c, d, e, f;
};
/*
fz_identity: Identity transform matrix.
*/
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 fz_matrix *fz_copy_matrix(fz_matrix *restrict m, const fz_matrix *restrict s)
{
*m = *s;
return m;
}
/*
fz_concat: 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 *result, const fz_matrix *left, const fz_matrix *right);
/*
fz_scale: 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(fz_matrix *m, float sx, float sy);
/*
fz_pre_scale: 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);
/*
fz_post_scale: 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);
/*
fz_shear: 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(fz_matrix *m, float sx, float sy);
/*
fz_pre_shear: 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);
/*
fz_rotate: 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(fz_matrix *m, float degrees);
/*
fz_pre_rotate: 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);
/*
fz_translate: 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(fz_matrix *m, float tx, float ty);
/*
fz_pre_translate: 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);
/*
fz_invert_matrix: 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 *inverse, const fz_matrix *matrix);
/*
fz_try_invert_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 *inverse, const fz_matrix *matrix);
/*
fz_is_rectilinear: 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(const fz_matrix *m);
/*
fz_matrix_expansion: Calculate average scaling factor of matrix.
*/
float fz_matrix_expansion(const fz_matrix *m); /* sumatrapdf */
/*
fz_intersect_rect: 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 *restrict a, const fz_rect *restrict b);
/*
fz_intersect_irect: 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 *restrict a, const fz_irect *restrict b);
/*
fz_union_rect: 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 *restrict a, const fz_rect *restrict b);
/*
fz_irect_from_rect: Convert a rect into the minimal bounding box
that covers the rectangle.
bbox: Place to store the returned bbox.
rect: The rectangle to convert to a bbox.
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.
Returns bbox (updated).
*/
fz_irect *fz_irect_from_rect(fz_irect *restrict bbox, const fz_rect *restrict rect);
/*
fz_round_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_irect *restrict bbox, const fz_rect *restrict rect);
/*
fz_rect_from_irect: 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_rect *restrict rect, const fz_irect *restrict bbox);
/*
fz_expand_rect: 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);
/*
fz_include_point_in_rect: 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, const fz_point *p);
/*
fz_translate_irect: 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);
/*
fz_contains_rect: Test rectangle inclusion.
Return true if a entirely contains b.
*/
int fz_contains_rect(const fz_rect *a, const fz_rect *b);
/*
fz_transform_point: 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 *restrict point, const fz_matrix *restrict transform);
fz_point *fz_transform_point_xy(fz_point *restrict point, const fz_matrix *restrict transform, float x, float y);
/*
fz_transform_vector: 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 *restrict vector, const fz_matrix *restrict transform);
/*
fz_transform_rect: 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 *restrict rect, const fz_matrix *restrict transform);
/*
fz_normalize_vector: Normalize a vector to length one.
*/
void fz_normalize_vector(fz_point *p);
void fz_gridfit_matrix(int as_tiled, fz_matrix *m);
float fz_matrix_max_expansion(const fz_matrix *m);
#endif

@ -0,0 +1,20 @@
#ifndef MUPDF_FITZ_GETOPT_H
#define MUPDF_FITZ_GETOPT_H
/*
getopt: Simple functions/variables for use in tools.
*/
extern int fz_getopt(int nargc, char * const *nargv, const char *ostr);
extern int fz_optind;
extern char *fz_optarg;
/*
Windows unicode versions.
*/
#ifdef _WIN32
extern int fz_getoptw(int nargc, wchar_t * const *nargv, const wchar_t *ostr);
extern int fz_optindw;
extern wchar_t *fz_optargw;
#endif
#endif

@ -0,0 +1,16 @@
#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"
void fz_purge_glyph_cache(fz_context *ctx);
fz_pixmap *fz_render_glyph_pixmap(fz_context *ctx, fz_font*, int, fz_matrix *, const fz_irect *scissor, int aa);
void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, const fz_matrix *trm, void *gstate, int nested_depth, fz_default_colorspaces *def_cs);
void fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid, int nested_depth);
void fz_dump_glyph_cache_stats(fz_context *ctx);
float fz_subpixel_adjust(fz_context *ctx, fz_matrix *ctm, fz_matrix *subpix_ctm, unsigned char *qe, unsigned char *qf);
#endif

@ -0,0 +1,133 @@
#ifndef MUPDF_FITZ_GLYPH_H
#define MUPDF_FITZ_GLYPH_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/colorspace.h"
/*
Glyphs represent a run length encoded set of pixels for a 2
dimensional region of a plane.
*/
typedef struct fz_glyph_s fz_glyph;
/*
fz_glyph_bbox: Return the bounding box for a glyph.
*/
fz_irect *fz_glyph_bbox(fz_context *ctx, fz_glyph *glyph, fz_irect *bbox);
/*
fz_glyph_width: Return the width of the glyph in pixels.
*/
int fz_glyph_width(fz_context *ctx, fz_glyph *glyph);
/*
fz_glyph_height: Return the height of the glyph in pixels.
*/
int fz_glyph_height(fz_context *ctx, fz_glyph *glyph);
/*
fz_new_glyph_from_pixmap: Create a new glyph from a pixmap
Returns a pointer to the new glyph. Throws exception on failure to
allocate.
*/
fz_glyph *fz_new_glyph_from_pixmap(fz_context *ctx, fz_pixmap *pix);
/*
fz_new_glyph_from_8bpp_data: Create a new glyph from 8bpp data
x, y: X and Y position for the glyph
w, h: Width and Height for the glyph
sp: Source Pointer to data
span: Increment from line to line of data
Returns a pointer to the new glyph. Throws exception on failure to
allocate.
*/
fz_glyph *fz_new_glyph_from_8bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span);
/*
fz_new_glyph_from_1bpp_data: Create a new glyph from 1bpp data
x, y: X and Y position for the glyph
w, h: Width and Height for the glyph
sp: Source Pointer to data
span: Increment from line to line of data
Returns a pointer to the new glyph. Throws exception on failure to
allocate.
*/
fz_glyph *fz_new_glyph_from_1bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span);
/*
fz_keep_glyph: Take a reference to a glyph.
pix: The glyph to increment the reference for.
Returns pix.
*/
fz_glyph *fz_keep_glyph(fz_context *ctx, fz_glyph *pix);
/*
fz_drop_glyph: Drop a reference and free a glyph.
Decrement the reference count for the glyph. When no
references remain the glyph will be freed.
*/
void fz_drop_glyph(fz_context *ctx, fz_glyph *pix);
/*
Glyphs represent a set of pixels for a 2 dimensional region of a
plane.
x, y: The minimum x and y coord of the region in pixels.
w, h: The width and height of the region in pixels.
samples: The sample data. The sample data is in a compressed format
designed to give reasonable compression, and to be fast to plot from.
The first sizeof(int) * h bytes of the table, when interpreted as
ints gives the offset within the data block of that lines data. An
offset of 0 indicates that that line is completely blank.
The data for individual lines is a sequence of bytes:
00000000 = end of lines data
LLLLLL00 = extend the length given in the next run by the 6 L bits
given here.
LLLLLL01 = A run of length L+1 transparent pixels.
LLLLLE10 = A run of length L+1 solid pixels. If E then this is the
last run on this line.
LLLLLE11 = A run of length L+1 intermediate pixels followed by L+1
bytes of literal pixel data. If E then this is the last run
on this line.
*/
struct fz_glyph_s
{
fz_storable storable;
int x, y, w, h;
fz_pixmap *pixmap;
size_t size;
unsigned char data[1];
};
fz_irect *fz_glyph_bbox_no_ctx(fz_glyph *src, fz_irect *bbox);
static inline size_t
fz_glyph_size(fz_context *ctx, fz_glyph *glyph)
{
if (glyph == NULL)
return 0;
return sizeof(fz_glyph) + glyph->size + fz_pixmap_size(ctx, glyph->pixmap);
}
#endif

@ -0,0 +1,32 @@
#ifndef MUPDF_FITZ_HASH_H
#define MUPDF_FITZ_HASH_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
/*
* Generic hash-table with fixed-length keys.
*
* The keys and values are NOT reference counted by the hash table.
* Callers are responsible for taking care the reference counts are correct.
* Inserting a duplicate entry will NOT overwrite the old value, and will
* return the old value.
*
* The drop_val callback function is only used to release values when the hash table
* is destroyed.
*/
typedef struct fz_hash_table_s fz_hash_table;
typedef void (fz_hash_table_drop_fn)(fz_context *ctx, void *val);
typedef void (fz_hash_table_for_each_fn)(fz_context *ctx, void *state, void *key, int keylen, void *val);
fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock, fz_hash_table_drop_fn *drop_val);
void fz_drop_hash_table(fz_context *ctx, fz_hash_table *table);
void *fz_hash_find(fz_context *ctx, fz_hash_table *table, const void *key);
void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *val);
void fz_hash_remove(fz_context *ctx, fz_hash_table *table, const void *key);
void fz_hash_for_each(fz_context *ctx, fz_hash_table *table, void *state, fz_hash_table_for_each_fn *callback);
#endif

@ -0,0 +1,331 @@
#ifndef MUPDF_FITZ_IMAGE_H
#define MUPDF_FITZ_IMAGE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/colorspace.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/stream.h"
#include "mupdf/fitz/compressed-buffer.h"
/*
Images are storable objects from which we can obtain fz_pixmaps.
These may be implemented as simple wrappers around a pixmap, or as
more complex things that decode at different subsample settings on
demand.
*/
typedef struct fz_image_s fz_image;
typedef struct fz_compressed_image_s fz_compressed_image;
typedef struct fz_pixmap_image_s fz_pixmap_image;
/*
fz_get_pixmap_from_image: Called to get a handle to a pixmap from an image.
image: The image to retrieve a pixmap from.
color_params: The color parameters (or NULL for defaults).
subarea: The subarea of the image that we actually care about (or NULL
to indicate the whole image).
trans: Optional, unless subarea is given. If given, then on entry this is
the transform that will be applied to the complete image. It should be
updated on exit to the transform to apply to the given subarea of the
image. This is used to calculate the desired width/height for subsampling.
w: If non-NULL, a pointer to an int to be updated on exit to the
width (in pixels) that the scaled output will cover.
h: If non-NULL, a pointer to an int to be updated on exit to the
height (in pixels) that the scaled output will cover.
Returns a non NULL pixmap pointer. May throw exceptions.
*/
fz_pixmap *fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subarea, fz_matrix *trans, int *w, int *h);
/*
fz_drop_image: Drop a reference to an image.
image: The image to drop a reference to.
*/
void fz_drop_image(fz_context *ctx, fz_image *image);
/*
fz_keep_image: Increment the reference count of an image.
image: The image to take a reference to.
Returns a pointer to the image.
*/
fz_image *fz_keep_image(fz_context *ctx, fz_image *image);
fz_image *fz_keep_image_store_key(fz_context *ctx, fz_image *image);
void fz_drop_image_store_key(fz_context *ctx, fz_image *image);
/*
fz_drop_image_fn: Function type to destroy an images data
when it's reference count reaches zero.
*/
typedef void (fz_drop_image_fn)(fz_context *ctx, fz_image *image);
/*
fz_get_pixmap_fn: Function type to get a decoded pixmap
for an image.
im: The image to decode.
subarea: NULL, or the subarea of the image required. Expressed
in terms of a rectangle in the original width/height of the
image. If non NULL, this should be updated by the function to
the actual subarea decoded - which must include the requested
area!
w, h: The actual width and height that the whole image would
need to be decoded to.
l2factor: On entry, the log 2 subsample factor required. If
possible the decode process can take care of (all or some) of
this subsampling, and must then update the value so the caller
knows what remains to be done.
Returns a reference to a decoded pixmap that satisfies the
requirements of the request.
*/
typedef fz_pixmap *(fz_image_get_pixmap_fn)(fz_context *ctx, fz_image *im, fz_irect *subarea, int w, int h, int *l2factor);
/*
fz_image_get_size_fn: Function type to get the given storage
size for an image.
Returns the size in bytes used for a given image.
*/
typedef size_t (fz_image_get_size_fn)(fz_context *, fz_image *);
/*
fz_new_image_of_size: Internal function to make a new fz_image structure
for a derived class.
w,h: Width and height of the created image.
bpc: Bits per component.
colorspace: The colorspace (determines the number of components,
and any color conversions required while decoding).
xres, yres: The X and Y resolutions respectively.
interpolate: 1 if interpolation should be used when decoding
this image, 0 otherwise.
imagemask: 1 if this is an imagemask (i.e. transparent), 0
otherwise.
decode: NULL, or a pointer to to a decode array. The default
decode array is [0 1] (repeated n times, for n color components).
colorkey: NULL, or a pointer to a colorkey array. The default
colorkey array is [0 255] (repeatd n times, for n color
components).
mask: NULL, or another image to use as a mask for this one.
A new reference is taken to this image. Supplying a masked
image as a mask to another image is illegal!
size: The size of the required allocated structure (the size of
the derived structure).
get: The function to be called to obtain a decoded pixmap.
get_size: The function to be called to return the storage size
used by this image.
drop: The function to be called to dispose of this image once
the last reference is dropped.
Returns a pointer to an allocated structure of the required size,
with the first sizeof(fz_image) bytes initialised as appropriate
given the supplied parameters, and the other bytes set to zero.
*/
fz_image *fz_new_image_of_size(fz_context *ctx,
int w,
int h,
int bpc,
fz_colorspace *colorspace,
int xres,
int yres,
int interpolate,
int imagemask,
float *decode,
int *colorkey,
fz_image *mask,
int size,
fz_image_get_pixmap_fn *get_pixmap,
fz_image_get_size_fn *get_size,
fz_drop_image_fn *drop);
#define fz_new_derived_image(CTX,W,H,B,CS,X,Y,I,IM,D,C,M,T,G,S,Z) \
((T*)Memento_label(fz_new_image_of_size(CTX,W,H,B,CS,X,Y,I,IM,D,C,M,sizeof(T),G,S,Z),#T))
/*
fz_new_image_from_compressed_buffer: Create an image based on
the data in the supplied compressed buffer.
w,h: Width and height of the created image.
bpc: Bits per component.
colorspace: The colorspace (determines the number of components,
and any color conversions required while decoding).
xres, yres: The X and Y resolutions respectively.
interpolate: 1 if interpolation should be used when decoding
this image, 0 otherwise.
imagemask: 1 if this is an imagemask (i.e. transparent), 0
otherwise.
decode: NULL, or a pointer to to a decode array. The default
decode array is [0 1] (repeated n times, for n color components).
colorkey: NULL, or a pointer to a colorkey array. The default
colorkey array is [0 255] (repeatd n times, for n color
components).
buffer: Buffer of compressed data and compression parameters.
Ownership of this reference is passed in.
mask: NULL, or another image to use as a mask for this one.
A new reference is taken to this image. Supplying a masked
image as a mask to another image is illegal!
*/
fz_image *fz_new_image_from_compressed_buffer(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, int xres, int yres, int interpolate, int imagemask, float *decode, int *colorkey, fz_compressed_buffer *buffer, fz_image *mask);
/*
fz_new_image_from_pixmap: Create an image from the given
pixmap.
pixmap: The pixmap to base the image upon. A new reference
to this is taken.
mask: NULL, or another image to use as a mask for this one.
A new reference is taken to this image. Supplying a masked
image as a mask to another image is illegal!
*/
fz_image *fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask);
/*
fz_new_image_from_buffer: Create a new image from a
buffer of data, inferring its type from the format
of the data.
*/
fz_image *fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer);
/*
fz_image_from_file: Create a new image from the contents
of a file, inferring its type from the format of the
data.
*/
fz_image *fz_new_image_from_file(fz_context *ctx, const char *path);
void fz_drop_image_imp(fz_context *ctx, fz_storable *image);
void fz_drop_image_base(fz_context *ctx, fz_image *image);
fz_pixmap *fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image *image, fz_irect *subarea, int indexed, int l2factor);
unsigned char *fz_indexed_colorspace_palette(fz_context *ctx, fz_colorspace *cs, int *high);
fz_pixmap *fz_expand_indexed_pixmap(fz_context *ctx, const fz_pixmap *src, int alpha);
size_t fz_image_size(fz_context *ctx, fz_image *im);
/*
Structure is public to allow other structures to
be derived from it. Do not access members directly.
*/
struct fz_image_s
{
fz_key_storable key_storable;
int w, h;
uint8_t n;
uint8_t bpc;
unsigned int imagemask:1;
unsigned int interpolate:1;
unsigned int use_colorkey:1;
unsigned int use_decode:1;
unsigned int invert_cmyk_jpeg:1;
unsigned int decoded:1;
unsigned int scalable:1;
fz_image *mask;
int xres; /* As given in the image, not necessarily as rendered */
int yres; /* As given in the image, not necessarily as rendered */
fz_colorspace *colorspace;
fz_drop_image_fn *drop_image;
fz_image_get_pixmap_fn *get_pixmap;
fz_image_get_size_fn *get_size;
int colorkey[FZ_MAX_COLORS * 2];
float decode[FZ_MAX_COLORS * 2];
};
fz_pixmap *fz_load_jpeg(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_jpx(fz_context *ctx, const unsigned char *data, size_t size, fz_colorspace *cs);
fz_pixmap *fz_load_png(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_tiff(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_jxr(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_gif(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_bmp(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_pnm(fz_context *ctx, const unsigned char *data, size_t size);
void fz_load_jpeg_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_jpx_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_png_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_tiff_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_jxr_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_gif_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_bmp_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_pnm_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
int fz_load_tiff_subimage_count(fz_context *ctx, const unsigned char *buf, size_t len);
fz_pixmap *fz_load_tiff_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage);
/*
fz_image_resolution: Request the natural resolution
of an image.
xres, yres: Pointers to ints to be updated with the
natural resolution of an image (or a sensible default
if not encoded).
*/
void fz_image_resolution(fz_image *image, int *xres, int *yres);
fz_pixmap *fz_compressed_image_tile(fz_context *ctx, fz_compressed_image *cimg);
void fz_set_compressed_image_tile(fz_context *ctx, fz_compressed_image *cimg, fz_pixmap *pix);
/*
fz_compressed_image_buffer: Retrieve the underlying compressed
data for an image.
Returns a pointer to the underlying data buffer for an image,
or NULL if this image is not based upon a compressed data
buffer.
This is not a reference counted structure, so no reference is
returned. Lifespan is limited to that of the image itself.
*/
fz_compressed_buffer *fz_compressed_image_buffer(fz_context *ctx, fz_image *image);
void fz_set_compressed_image_buffer(fz_context *ctx, fz_compressed_image *cimg, fz_compressed_buffer *buf);
/*
fz_pixmap_image_tile: Retried the underlying fz_pixmap
for an image.
Returns a pointer to the underlying fz_pixmap for an image,
or NULL if this image is not based upon an fz_pixmap.
No reference is returned. Lifespan is limited to that of
the image itself. If required, use fz_keep_pixmap to take
a reference to keep it longer.
*/
fz_pixmap *fz_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *cimg);
void fz_set_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *cimg, fz_pixmap *pix);
#endif

@ -0,0 +1,55 @@
#ifndef MUPDF_FITZ_LINK_H
#define MUPDF_FITZ_LINK_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
/*
Links
*/
typedef struct fz_link_s fz_link;
/*
fz_link is a list of interactive links on a page.
There is no relation between the order of the links in the
list and the order they appear on the page. The list of links
for a given page can be obtained from fz_load_links.
A link is reference counted. Dropping a reference to a link is
done by calling fz_drop_link.
rect: The hot zone. The area that can be clicked in
untransformed coordinates.
uri: Link destinations come in two forms: internal and external.
Internal links refer to other pages in the same document.
External links are URLs to other documents.
next: A pointer to the next link on the same page.
*/
struct fz_link_s
{
int refs;
fz_link *next;
fz_rect rect;
void *doc;
char *uri;
};
fz_link *fz_new_link(fz_context *ctx, const fz_rect *bbox, void *doc, const char *uri);
fz_link *fz_keep_link(fz_context *ctx, fz_link *link);
/*
Checks if a link destination is external or internal.
*/
int fz_is_external_link(fz_context *ctx, const char *uri);
/*
fz_drop_link: Drop and free a list of links.
*/
void fz_drop_link(fz_context *ctx, fz_link *link);
#endif

@ -0,0 +1,49 @@
#ifndef MUPDF_FITZ_OUTLINE_H
#define MUPDF_FITZ_OUTLINE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/link.h"
#include "mupdf/fitz/output.h"
/* Outline */
/*
fz_outline is a tree of the outline of a document (also known
as table of contents).
title: Title of outline item using UTF-8 encoding. May be NULL
if the outline item has no text string.
uri: Destination in the document to be displayed when this
outline item is activated. May be an internal or external
link, or NULL if the outline item does not have a destination.
page: The page number of an internal link, or -1 for external
links or links with no destination.
next: The next outline item at the same level as this outline
item. May be NULL if no more outline items exist at this level.
down: The outline items immediate children in the hierarchy.
May be NULL if no children exist.
*/
typedef struct fz_outline_s fz_outline;
struct fz_outline_s
{
int refs;
char *title;
char *uri;
int page;
float x, y;
fz_outline *next;
fz_outline *down;
int is_open;
};
fz_outline *fz_new_outline(fz_context *ctx);
fz_outline *fz_keep_outline(fz_context *ctx, fz_outline *outline);
void fz_drop_outline(fz_context *ctx, fz_outline *outline);
#endif

@ -0,0 +1,88 @@
#ifndef MUPDF_FITZ_OUTPUT_PCL_H
#define MUPDF_FITZ_OUTPUT_PCL_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/bitmap.h"
/*
PCL output
*/
typedef struct fz_pcl_options_s fz_pcl_options;
struct fz_pcl_options_s
{
/* Features of a particular printer */
int features;
const char *odd_page_init;
const char *even_page_init;
/* Options for this job */
int tumble;
int duplex_set;
int duplex;
int paper_size;
int manual_feed_set;
int manual_feed;
int media_position_set;
int media_position;
int orientation;
/* Updated as we move through the job */
int page_count;
};
/*
fz_pcl_preset: Initialize PCL option struct for a given preset.
Currently defined presets include:
generic Generic PCL printer
ljet4 HP DeskJet
dj500 HP DeskJet 500
fs600 Kyocera FS-600
lj HP LaserJet, HP LaserJet Plus
lj2 HP LaserJet IIp, HP LaserJet IId
lj3 HP LaserJet III
lj3d HP LaserJet IIId
lj4 HP LaserJet 4
lj4pl HP LaserJet 4 PL
lj4d HP LaserJet 4d
lp2563b HP 2563B line printer
oce9050 Oce 9050 Line printer
*/
void fz_pcl_preset(fz_context *ctx, fz_pcl_options *opts, const char *preset);
/*
fz_parse_pcl_options: Parse PCL options.
Currently defined options and values are as follows:
preset=X Either "generic" or one of the presets as for fz_pcl_preset.
spacing=0 No vertical spacing capability
spacing=1 PCL 3 spacing (<ESC>*p+<n>Y)
spacing=2 PCL 4 spacing (<ESC>*b<n>Y)
spacing=3 PCL 5 spacing (<ESC>*b<n>Y and clear seed row)
mode2 Disable/Enable mode 2 graphics compression
mode3 Disable/Enable mode 3 graphics compression
eog_reset End of graphics (<ESC>*rB) resets all parameters
has_duplex Duplex supported (<ESC>&l<duplex>S)
has_papersize Papersize setting supported (<ESC>&l<sizecode>A)
has_copies Number of copies supported (<ESC>&l<copies>X)
is_ljet4pjl Disable/Enable HP 4PJL model-specific output
is_oce9050 Disable/Enable Oce 9050 model-specific output
*/
fz_pcl_options *fz_parse_pcl_options(fz_context *ctx, fz_pcl_options *opts, const char *args);
fz_band_writer *fz_new_mono_pcl_band_writer(fz_context *ctx, fz_output *out, const fz_pcl_options *options);
void fz_write_bitmap_as_pcl(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap, const fz_pcl_options *pcl);
void fz_save_bitmap_as_pcl(fz_context *ctx, fz_bitmap *bitmap, char *filename, int append, const fz_pcl_options *pcl);
fz_band_writer *fz_new_color_pcl_band_writer(fz_context *ctx, fz_output *out, const fz_pcl_options *options);
void fz_write_pixmap_as_pcl(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pcl_options *pcl);
void fz_save_pixmap_as_pcl(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append, const fz_pcl_options *pcl);
#endif

@ -0,0 +1,41 @@
#ifndef MUPDF_FITZ_OUTPUT_PCLM_H
#define MUPDF_FITZ_OUTPUT_PCLM_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/bitmap.h"
/*
PCLm output
*/
typedef struct fz_pclm_options_s fz_pclm_options;
struct fz_pclm_options_s
{
int compress;
int strip_height;
/* Updated as we move through the job */
int page_count;
};
/*
fz_parse_pclm_options: Parse PCLm options.
Currently defined options and values are as follows:
compression=none: No compression
compression=flate: Flate compression
strip-height=n: Strip height (default 16)
*/
fz_pclm_options *fz_parse_pclm_options(fz_context *ctx, fz_pclm_options *opts, const char *args);
fz_band_writer *fz_new_pclm_band_writer(fz_context *ctx, fz_output *out, const fz_pclm_options *options);
fz_document_writer *fz_new_pclm_writer(fz_context *ctx, const char *path, const char *options);
void fz_write_pixmap_as_pclm(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pclm_options *options);
void fz_save_pixmap_as_pclm(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append, const fz_pclm_options *options);
#endif

@ -0,0 +1,36 @@
#ifndef MUPDF_FITZ_OUTPUT_PNG_H
#define MUPDF_FITZ_OUTPUT_PNG_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/bitmap.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/image.h"
/*
fz_save_pixmap_as_png: Save a pixmap as a PNG image file.
*/
void fz_save_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/*
Write a pixmap to an output stream in PNG format.
*/
void fz_write_pixmap_as_png(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap);
/*
fz_new_png_band_writer: Obtain a fz_band_writer instance
for producing PNG output.
*/
fz_band_writer *fz_new_png_band_writer(fz_context *ctx, fz_output *out);
/*
Create a new buffer containing the image/pixmap in PNG format.
*/
fz_buffer *fz_new_buffer_from_image_as_png(fz_context *ctx, fz_image *image, const fz_color_params *color_params);
fz_buffer *fz_new_buffer_from_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, const fz_color_params *color_params);
#endif

@ -0,0 +1,51 @@
#ifndef MUPDF_FITZ_OUTPUT_PNM_H
#define MUPDF_FITZ_OUTPUT_PNM_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/bitmap.h"
/*
fz_save_pixmap_as_pnm: Save a pixmap as a PNM image file.
*/
void fz_save_pixmap_as_pnm(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
void fz_write_pixmap_as_pnm(fz_context *ctx, fz_output *out, fz_pixmap *pixmap);
fz_band_writer *fz_new_pnm_band_writer(fz_context *ctx, fz_output *out);
/*
fz_save_pixmap_as_pam: Save a pixmap as a PAM image file.
*/
void fz_save_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
void fz_write_pixmap_as_pam(fz_context *ctx, fz_output *out, fz_pixmap *pixmap);
fz_band_writer *fz_new_pam_band_writer(fz_context *ctx, fz_output *out);
/*
fz_save_bitmap_as_pbm: Save a bitmap as a PBM image file.
*/
void fz_save_bitmap_as_pbm(fz_context *ctx, fz_bitmap *bitmap, const char *filename);
void fz_write_bitmap_as_pbm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap);
fz_band_writer *fz_new_pbm_band_writer(fz_context *ctx, fz_output *out);
void fz_save_pixmap_as_pbm(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/*
fz_save_bitmap_as_pkm: Save a 4bpp cmyk bitmap as a PAM image file.
*/
void fz_save_bitmap_as_pkm(fz_context *ctx, fz_bitmap *bitmap, const char *filename);
void fz_write_bitmap_as_pkm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap);
fz_band_writer *fz_new_pkm_band_writer(fz_context *ctx, fz_output *out);
void fz_save_pixmap_as_pkm(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
#endif

@ -0,0 +1,23 @@
#ifndef MUPDF_FITZ_OUTPUT_PS_H
#define MUPDF_FITZ_OUTPUT_PS_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
/*
PS (image) output
*/
void fz_write_pixmap_as_ps(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap);
void fz_save_pixmap_as_ps(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append);
void fz_write_ps_file_header(fz_context *ctx, fz_output *out);
fz_band_writer *fz_new_ps_band_writer(fz_context *ctx, fz_output *out);
void fz_write_ps_file_trailer(fz_context *ctx, fz_output *out, int pages);
#endif

@ -0,0 +1,30 @@
#ifndef MUPDF_FITZ_OUTPUT_PSD_H
#define MUPDF_FITZ_OUTPUT_PSD_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/bitmap.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/image.h"
/*
fz_save_pixmap_as_psd: Save a pixmap as a PSD image file.
*/
void fz_save_pixmap_as_psd(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/*
Write a pixmap to an output stream in PSD format.
*/
void fz_write_pixmap_as_psd(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap);
/*
fz_new_psd_band_writer: Obtain a fz_band_writer instance
for producing PSD output.
*/
fz_band_writer *fz_new_psd_band_writer(fz_context *ctx, fz_output *out);
#endif

@ -0,0 +1,116 @@
#ifndef MUPDF_FITZ_OUTPUT_PWG_H
#define MUPDF_FITZ_OUTPUT_PWG_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/bitmap.h"
typedef struct fz_pwg_options_s fz_pwg_options;
struct fz_pwg_options_s
{
/* These are not interpreted as CStrings by the writing code, but
* are rather copied directly out. */
char media_class[64];
char media_color[64];
char media_type[64];
char output_type[64];
unsigned int advance_distance;
int advance_media;
int collate;
int cut_media;
int duplex;
int insert_sheet;
int jog;
int leading_edge;
int manual_feed;
unsigned int media_position;
unsigned int media_weight;
int mirror_print;
int negative_print;
unsigned int num_copies;
int orientation;
int output_face_up;
unsigned int PageSize[2];
int separations;
int tray_switch;
int tumble;
int media_type_num;
int compression;
unsigned int row_count;
unsigned int row_feed;
unsigned int row_step;
/* These are not interpreted as CStrings by the writing code, but
* are rather copied directly out. */
char rendering_intent[64];
char page_size_name[64];
};
/*
fz_save_pixmap_as_pwg: Save a pixmap as a pwg
filename: The filename to save as (including extension).
append: If non-zero, then append a new page to existing file.
pwg: NULL, or a pointer to an options structure (initialised to zero
before being filled in, for future expansion).
*/
void fz_save_pixmap_as_pwg(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append, const fz_pwg_options *pwg);
/*
fz_save_bitmap_as_pwg: Save a bitmap as a pwg
filename: The filename to save as (including extension).
append: If non-zero, then append a new page to existing file.
pwg: NULL, or a pointer to an options structure (initialised to zero
before being filled in, for future expansion).
*/
void fz_save_bitmap_as_pwg(fz_context *ctx, fz_bitmap *bitmap, char *filename, int append, const fz_pwg_options *pwg);
/*
Output a pixmap to an output stream as a pwg raster.
*/
void fz_write_pixmap_as_pwg(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pwg_options *pwg);
/*
Output a bitmap to an output stream as a pwg raster.
*/
void fz_write_bitmap_as_pwg(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap, const fz_pwg_options *pwg);
/*
Output the file header to a pwg stream, ready for pages to follow it.
*/
void fz_write_pwg_file_header(fz_context *ctx, fz_output *out);
/*
Output a page to a pwg stream to follow a header, or other pages.
*/
void fz_write_pixmap_as_pwg_page(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pwg_options *pwg);
/*
Output a bitmap page to a pwg stream to follow a header, or other pages.
*/
void fz_write_bitmap_as_pwg_page(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap, const fz_pwg_options *pwg);
/*
fz_new_mono_pwg_band_writer: Generate a new band writer for
PWG format images.
*/
fz_band_writer *fz_new_mono_pwg_band_writer(fz_context *ctx, fz_output *out, const fz_pwg_options *pwg);
/*
fz_new_pwg_band_writer: Generate a new band writer for
contone PWG format images.
*/
fz_band_writer *fz_new_pwg_band_writer(fz_context *ctx, fz_output *out, const fz_pwg_options *pwg);
#endif

@ -0,0 +1,30 @@
#ifndef MUPDF_FITZ_OUTPUT_SVG_H
#define MUPDF_FITZ_OUTPUT_SVG_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/device.h"
#include "mupdf/fitz/output.h"
enum {
FZ_SVG_TEXT_AS_PATH = 0,
FZ_SVG_TEXT_AS_TEXT = 1,
};
/*
fz_new_svg_device: Create a device that outputs (single page)
SVG files to the given output stream.
output: The output stream to send the constructed SVG page to.
page_width, page_height: The page dimensions to use (in points).
text_format: How to emit text. One of the following values:
FZ_SVG_TEXT_AS_TEXT: As <text> elements with possible layout errors and mismatching fonts.
FZ_SVG_TEXT_AS_PATH: As <path> elements with exact visual appearance.
reuse_images: Share image resources using <symbol> definitions.
*/
fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width, float page_height, int text_format, int reuse_images);
#endif

@ -0,0 +1,37 @@
#ifndef MUPDF_FITZ_OUTPUT_TGA_H
#define MUPDF_FITZ_OUTPUT_TGA_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
/*
fz_save_pixmap_as_tga: Save a pixmap as a TGA image file.
Can accept RGB, BGR or Grayscale pixmaps, with or without
alpha.
*/
void fz_save_pixmap_as_tga(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/*
Write a pixmap to an output stream in TGA format.
Can accept RGB, BGR or Grayscale pixmaps, with or without
alpha.
*/
void fz_write_pixmap_as_tga(fz_context *ctx, fz_output *out, fz_pixmap *pixmap);
/*
fz_new_tga_band_writer: Generate a new band writer for TGA
format images. Note that image must be generated vertically
flipped for use with this writer!
Can accept RGB, BGR or Grayscale pixmaps, with or without
alpha.
is_bgr: True, if the image is generated in bgr format.
*/
fz_band_writer *fz_new_tga_band_writer(fz_context *ctx, fz_output *out, int is_bgr);
#endif

@ -0,0 +1,317 @@
#ifndef MUPDF_FITZ_OUTPUT_H
#define MUPDF_FITZ_OUTPUT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/string-util.h"
#include "mupdf/fitz/stream.h"
/*
Generic output streams - generalise between outputting to a file,
a buffer, etc.
*/
typedef struct fz_output_s fz_output;
/*
fz_output_write_fn: A function type for use when implementing
fz_outputs. The supplied function of this type is called
whenever data is written to the output.
state: The state for the output stream.
data: a pointer to a buffer of data to write.
n: The number of bytes of data to write.
*/
typedef void (fz_output_write_fn)(fz_context *ctx, void *state, const void *data, size_t n);
/*
fz_output_seek_fn: A function type for use when implementing
fz_outputs. The supplied function of this type is called when
fz_seek_output is requested.
state: The output stream state to seek within.
offset, whence: as defined for fs_seek_output.
*/
typedef void (fz_output_seek_fn)(fz_context *ctx, void *state, int64_t offset, int whence);
/*
fz_output_tell_fn: A function type for use when implementing
fz_outputs. The supplied function of this type is called when
fz_tell_output is requested.
state: The output stream state to report on.
Returns the offset within the output stream.
*/
typedef int64_t (fz_output_tell_fn)(fz_context *ctx, void *state);
/*
fz_output_close_fn: A function type for use when implementing
fz_outputs. The supplied function of this type is called
when the output stream is closed, to flush any pending writes.
*/
typedef void (fz_output_close_fn)(fz_context *ctx, void *state);
/*
fz_output_drop_fn: A function type for use when implementing
fz_outputs. The supplied function of this type is called
when the output stream is dropped, to release the stream specific
state information.
*/
typedef void (fz_output_drop_fn)(fz_context *ctx, void *state);
/*
fz_stream_from_output_fn: A function type for use when implementing
fz_outputs. The supplied function of this type is called
when the fz_stream_from_output is called.
*/
typedef fz_stream *(fz_stream_from_output_fn)(fz_context *ctx, void *state);
struct fz_output_s
{
void *state;
fz_output_write_fn *write;
fz_output_seek_fn *seek;
fz_output_tell_fn *tell;
fz_output_close_fn *close;
fz_output_drop_fn *drop;
fz_stream_from_output_fn *as_stream;
char *bp, *wp, *ep;
};
/*
fz_new_output: Create a new output object with the given
internal state and function pointers.
state: Internal state (opaque to everything but implementation).
write: Function to output a given buffer.
close: Cleanup function to destroy state when output closed.
May permissibly be null.
*/
fz_output *fz_new_output(fz_context *ctx, int bufsiz, void *state, fz_output_write_fn *write, fz_output_close_fn *close, fz_output_drop_fn *drop);
/*
fz_new_output_with_path: Open an output stream that writes to a
given path.
filename: The filename to write to (specified in UTF-8).
append: non-zero if we should append to the file, rather than
overwriting it.
*/
fz_output *fz_new_output_with_path(fz_context *, const char *filename, int append);
/*
fz_new_output_with_buffer: Open an output stream that appends
to a buffer.
buf: The buffer to append to.
*/
fz_output *fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf);
/*
fz_stdout: The standard out output stream. By default
this stream writes to stdout. This may be overridden
using fz_set_stdout.
*/
fz_output *fz_stdout(fz_context *ctx);
/*
fz_stderr: The standard error output stream. By default
this stream writes to stderr. This may be overridden
using fz_set_stderr.
*/
fz_output *fz_stderr(fz_context *ctx);
/*
fz_set_stdout: Replace default standard output stream
with a given stream.
out: The new stream to use.
*/
void fz_set_stdout(fz_context *ctx, fz_output *out);
/*
fz_set_stderr: Replace default standard error stream
with a given stream.
err: The new stream to use.
*/
void fz_set_stderr(fz_context *ctx, fz_output *err);
/*
fz_write_printf: Format and write data to an output stream.
See fz_vsnprintf for formatting details.
*/
void fz_write_printf(fz_context *ctx, fz_output *out, const char *fmt, ...);
/*
fz_write_vprintf: va_list version of fz_write_printf.
*/
void fz_write_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list ap);
/*
fz_seek_output: Seek to the specified file position.
See fseek for arguments.
Throw an error on unseekable outputs.
*/
void fz_seek_output(fz_context *ctx, fz_output *out, int64_t off, int whence);
/*
fz_tell_output: Return the current file position.
Throw an error on untellable outputs.
*/
int64_t fz_tell_output(fz_context *ctx, fz_output *out);
/*
fz_flush_output: Flush unwritten data.
*/
void fz_flush_output(fz_context *ctx, fz_output *out);
/*
fz_close_output: Flush pending output and close an output stream.
*/
void fz_close_output(fz_context *, fz_output *);
/*
fz_drop_output: Free an output stream. Don't forget to close it first!
*/
void fz_drop_output(fz_context *, fz_output *);
/*
fz_stream_from_output: obtain the fz_output in the form of a fz_stream
This allows data to be read back from some forms of fz_output object.
When finished reading, the fz_stream should be released by calling
fz_drop_stream. Until the fz_stream is dropped, no further operations
should be performed on the fz_output object.
*/
fz_stream *fz_stream_from_output(fz_context *, fz_output *);
/*
fz_write_data: Write data to output.
data: Pointer to data to write.
size: Size of data to write in bytes.
*/
void fz_write_data(fz_context *ctx, fz_output *out, const void *data, size_t size);
/*
fz_write_string: Write a string. Does not write zero terminator.
*/
void fz_write_string(fz_context *ctx, fz_output *out, const char *s);
/*
fz_write_int32_be: Write a big-endian 32-bit binary integer.
*/
void fz_write_int32_be(fz_context *ctx, fz_output *out, int x);
/*
fz_write_int32_le: Write a little-endian 32-bit binary integer.
*/
void fz_write_int32_le(fz_context *ctx, fz_output *out, int x);
/*
fz_write_int16_be: Write a big-endian 16-bit binary integer.
*/
void fz_write_int16_be(fz_context *ctx, fz_output *out, int x);
/*
fz_write_int16_le: Write a little-endian 16-bit binary integer.
*/
void fz_write_int16_le(fz_context *ctx, fz_output *out, int x);
/*
fz_write_byte: Write a single byte.
*/
void fz_write_byte(fz_context *ctx, fz_output *out, unsigned char x);
/*
fz_write_rune: Write a UTF-8 encoded unicode character.
*/
void fz_write_rune(fz_context *ctx, fz_output *out, int rune);
/*
fz_write_base64: Write base64 encoded data.
*/
void fz_write_base64(fz_context *ctx, fz_output *out, const unsigned char *data, int size, int newline);
void fz_write_base64_buffer(fz_context *ctx, fz_output *out, fz_buffer *data, int newline);
/*
fz_format_string: Our customised 'printf'-like string formatter.
Takes %c, %d, %s, %u, %x, as usual.
Modifiers are not supported except for zero-padding ints (e.g. %02d, %03u, %04x, etc).
%g output in "as short as possible hopefully lossless non-exponent" form,
see fz_ftoa for specifics.
%f and %e output as usual.
%C outputs a utf8 encoded int.
%M outputs a fz_matrix*. %R outputs a fz_rect*. %P outputs a fz_point*.
%q and %( output escaped strings in C/PDF syntax.
%l{d,u,x} indicates that the values are int64_t.
%z{d,u,x} indicates that the value is a size_t.
user: An opaque pointer that is passed to the emit function.
emit: A function pointer called to emit output bytes as the string is being formatted.
*/
void
fz_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void *user, int c), const char *fmt, va_list args);
/*
fz_vsnprintf: A vsnprintf work-alike, using our custom formatter.
*/
size_t fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args);
/*
fz_snprintf: The non va_list equivalent of fz_vsnprintf.
*/
size_t fz_snprintf(char *buffer, size_t space, const char *fmt, ...);
/*
fz_asprintf: Print to allocated string.
*/
char *fz_asprintf(fz_context *ctx, const char *fmt, ...);
/*
fz_tempfilename: Get a temporary filename based upon 'base'.
'hint' is the path of a file (normally the existing document file)
supplied to give the function an idea of what directory to use. This
may or may not be used depending on the implementation's whim.
The returned path must be freed.
*/
char *fz_tempfilename(fz_context *ctx, const char *base, const char *hint);
/*
fz_save_buffer: Save contents of a buffer to file.
*/
void fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename);
/*
Compression and other filtering outputs.
These outputs write encoded data to another output. Create a filter
output with the destination, write to the filter, then drop it when
you're done. These can also be chained together, for example to write
ASCII Hex encoded, Deflate compressed, and RC4 encrypted data to a
buffer output.
Output streams don't use reference counting, so make sure to drop all
of the filters in the reverse order of creation so that data is flushed
properly.
*/
fz_output *fz_new_asciihex_output(fz_context *ctx, fz_output *chain);
fz_output *fz_new_ascii85_output(fz_context *ctx, fz_output *chain);
fz_output *fz_new_rle_output(fz_context *ctx, fz_output *chain);
fz_output *fz_new_arc4_output(fz_context *ctx, fz_output *chain, unsigned char *key, size_t keylen);
fz_output *fz_new_deflate_output(fz_context *ctx, fz_output *chain, int effort, int raw);
#endif

@ -0,0 +1,434 @@
#ifndef MUPDF_FITZ_PATH_H
#define MUPDF_FITZ_PATH_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
/*
* Vector path buffer.
* It can be stroked and dashed, or be filled.
* It has a fill rule (nonzero or even_odd).
*
* When rendering, they are flattened, stroked and dashed straight
* into the Global Edge List.
*/
typedef struct fz_path_s fz_path;
typedef struct fz_stroke_state_s fz_stroke_state;
typedef enum fz_linecap_e
{
FZ_LINECAP_BUTT = 0,
FZ_LINECAP_ROUND = 1,
FZ_LINECAP_SQUARE = 2,
FZ_LINECAP_TRIANGLE = 3
} fz_linecap;
typedef enum fz_linejoin_e
{
FZ_LINEJOIN_MITER = 0,
FZ_LINEJOIN_ROUND = 1,
FZ_LINEJOIN_BEVEL = 2,
FZ_LINEJOIN_MITER_XPS = 3
} fz_linejoin;
struct fz_stroke_state_s
{
int refs;
fz_linecap start_cap, dash_cap, end_cap;
fz_linejoin linejoin;
float linewidth;
float miterlimit;
float dash_phase;
int dash_len;
float dash_list[32];
};
typedef struct
{
/* Compulsory ones */
void (*moveto)(fz_context *ctx, void *arg, float x, float y);
void (*lineto)(fz_context *ctx, void *arg, float x, float y);
void (*curveto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2, float x3, float y3);
void (*closepath)(fz_context *ctx, void *arg);
/* Optional ones */
void (*quadto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2);
void (*curvetov)(fz_context *ctx, void *arg, float x2, float y2, float x3, float y3);
void (*curvetoy)(fz_context *ctx, void *arg, float x1, float y1, float x3, float y3);
void (*rectto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2);
} fz_path_walker;
/*
fz_walk_path: Walk the segments of a path, calling the
appropriate callback function from a given set for each
segment of the path.
path: The path to walk.
walker: The set of callback functions to use. The first
4 callback pointers in the set must be non-NULL. The
subsequent ones can either be supplied, or can be left
as NULL, in which case the top 4 functions will be
called as appropriate to simulate them.
arg: An opaque argument passed in to each callback.
Exceptions will only be thrown if the underlying callback
functions throw them.
*/
void fz_walk_path(fz_context *ctx, const fz_path *path, const fz_path_walker *walker, void *arg);
/*
fz_new_path: Create an empty path, and return
a reference to it.
Throws exception on failure to allocate.
*/
fz_path *fz_new_path(fz_context *ctx);
/*
fz_keep_path: Take an additional reference to
a path.
No modifications should be carried out on a path
to which more than one reference is held, as
this can cause race conditions.
Never throws exceptions.
*/
fz_path *fz_keep_path(fz_context *ctx, const fz_path *path);
/*
fz_drop_path: Drop a reference to a path,
destroying the path if it is the last
reference.
Never throws exceptions.
*/
void fz_drop_path(fz_context *ctx, const fz_path *path);
/*
fz_trim_path: Minimise the internal storage
used by a path.
As paths are constructed, the internal buffers
grow. To avoid repeated reallocations they
grow with some spare space. Once a path has
been fully constructed, this call allows the
excess space to be trimmed.
Never throws exceptions.
*/
void fz_trim_path(fz_context *ctx, fz_path *path);
/*
fz_packed_path_size: Return the number of
bytes required to pack a path.
Never throws exceptions.
*/
int fz_packed_path_size(const fz_path *path);
/*
fz_pack_path: Pack a path into the given block.
To minimise the size of paths, this function allows them to be
packed into a buffer with other information. Paths can be used
interchangeably regardless of how they are packed.
pack: Pointer to a block of data to pack the path into. Should
be aligned by the caller to the same alignment as required for
a fz_path pointer.
max: The number of bytes available in the block.
If max < sizeof(fz_path) then an exception will
be thrown. If max >= the value returned by
fz_packed_path_size, then this call will never
fail, except in low memory situations with large
paths.
path: The path to pack.
Returns the number of bytes within the block used. Callers can
access the packed path data by casting the value of pack on
entry to be a fz_path *.
Throws exceptions on failure to allocate, or if
max < sizeof(fz_path).
Implementation details: Paths can be 'unpacked', 'flat', or
'open'. Standard paths, as created are 'unpacked'. Paths that
will pack into less than max bytes will be packed as 'flat',
unless they are too large (where large indicates that they
exceed some private implementation defined limits, currently
including having more than 256 coordinates or commands).
Large paths are 'open' packed as a header into the given block,
plus pointers to other data blocks.
Users should not have to care about whether paths are 'open'
or 'flat' packed. Simply pack a path (if required), and then
forget about the details.
*/
int fz_pack_path(fz_context *ctx, uint8_t *pack, int max, const fz_path *path);
/*
fz_clone_path: Clone the data for a path.
This is used in preference to fz_keep_path when a whole
new copy of a path is required, rather than just a shared
pointer. This probably indicates that the path is about to
be modified.
path: path to clone.
Throws exceptions on failure to allocate.
*/
fz_path *fz_clone_path(fz_context *ctx, fz_path *path);
/*
fz_currentpoint: Return the current point that a path has
reached or (0,0) if empty.
path: path to return the current point of.
*/
fz_point fz_currentpoint(fz_context *ctx, fz_path *path);
/*
fz_moveto: Append a 'moveto' command to a path.
This 'opens' a path.
path: The path to modify.
x, y: The coordinate to move to.
Throws exceptions on failure to allocate.
*/
void fz_moveto(fz_context *ctx, fz_path *path, float x, float y);
/*
fz_lineto: Append a 'lineto' command to an open path.
path: The path to modify.
x, y: The coordinate to line to.
Throws exceptions on failure to allocate.
*/
void fz_lineto(fz_context *ctx, fz_path *path, float x, float y);
/*
fz_rectto: Append a 'rectto' command to an open path.
The rectangle is equivalent to:
moveto x0 y0
lineto x1 y0
lineto x1 y1
lineto x0 y1
closepath
path: The path to modify.
x0, y0: First corner of the rectangle.
x1, y1: Second corner of the rectangle.
Throws exceptions on failure to allocate.
*/
void fz_rectto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
/*
fz_quadto: Append a 'quadto' command to an open path. (For a
quadratic bezier).
path: The path to modify.
x0, y0: The control coordinates for the quadratic curve.
x1, y1: The end coordinates for the quadratic curve.
Throws exceptions on failure to allocate.
*/
void fz_quadto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
/*
fz_curveto: Append a 'curveto' command to an open path. (For a
cubic bezier).
path: The path to modify.
x0, y0: The coordinates of the first control point for the
curve.
x1, y1: The coordinates of the second control point for the
curve.
x2, y2: The end coordinates for the curve.
Throws exceptions on failure to allocate.
*/
void fz_curveto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1, float x2, float y2);
/*
fz_curvetov: Append a 'curvetov' command to an open path. (For a
cubic bezier with the first control coordinate equal to
the start point).
path: The path to modify.
x1, y1: The coordinates of the second control point for the
curve.
x2, y2: The end coordinates for the curve.
Throws exceptions on failure to allocate.
*/
void fz_curvetov(fz_context *ctx, fz_path *path, float x1, float y1, float x2, float y2);
/*
fz_curvetoy: Append a 'curvetoy' command to an open path. (For a
cubic bezier with the second control coordinate equal to
the end point).
path: The path to modify.
x0, y0: The coordinates of the first control point for the
curve.
x2, y2: The end coordinates for the curve (and the second
control coordinate).
Throws exceptions on failure to allocate.
*/
void fz_curvetoy(fz_context *ctx, fz_path *path, float x0, float y0, float x2, float y2);
/*
fz_closepath: Close the current subpath.
path: The path to modify.
Throws exceptions on failure to allocate, and illegal
path closes (i.e. closing a non open path).
*/
void fz_closepath(fz_context *ctx, fz_path *path);
/*
fz_transform_path: Transform a path by a given
matrix.
path: The path to modify (must not be a packed path).
transform: The transform to apply.
Throws exceptions if the path is packed, or on failure
to allocate.
*/
void fz_transform_path(fz_context *ctx, fz_path *path, const fz_matrix *transform);
/*
fz_bound_path: Return a bounding rectangle for a path.
path: The path to bound.
stroke: If NULL, the bounding rectangle given is for
the filled path. If non-NULL the bounding rectangle
given is for the path stroked with the given attributes.
ctm: The matrix to apply to the path during stroking.
r: Pointer to a fz_rect which will be used to hold
the result.
Returns r, updated to contain the bounding rectangle.
*/
fz_rect *fz_bound_path(fz_context *ctx, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *r);
fz_rect *fz_adjust_rect_for_stroke(fz_context *ctx, fz_rect *r, const fz_stroke_state *stroke, const fz_matrix *ctm);
extern const fz_stroke_state fz_default_stroke_state;
/*
fz_new_stroke_state: Create a new (empty) stroke state
structure (with no dash data) and return a reference to it.
Throws exception on failure to allocate.
*/
fz_stroke_state *fz_new_stroke_state(fz_context *ctx);
/*
fz_new_stroke_state_with_dash_len: Create a new (empty)
stroke state structure, with room for dash data of the
given length, and return a reference to it.
len: The number of dash elements to allow room for.
Throws exception on failure to allocate.
*/
fz_stroke_state *fz_new_stroke_state_with_dash_len(fz_context *ctx, int len);
/*
fz_keep_stroke_state: Take an additional reference to
a stroke state structure.
No modifications should be carried out on a stroke
state to which more than one reference is held, as
this can cause race conditions.
Never throws exceptions.
*/
fz_stroke_state *fz_keep_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
/*
fz_drop_stroke_state: Drop a reference to a stroke
state structure, destroying the structure if it is
the last reference.
Never throws exceptions.
*/
void fz_drop_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
/*
fz_unshare_stroke_state: Given a reference to a
(possibly) shared stroke_state structure, return
a reference to an equivalent stroke_state structure
that is guaranteed to be unshared (i.e. one that can
safely be modified).
shared: The reference to a (possibly) shared structure
to unshare. Ownership of this reference is passed in
to this function, even in the case of exceptions being
thrown.
Exceptions may be thrown in the event of failure to
allocate if required.
*/
fz_stroke_state *fz_unshare_stroke_state(fz_context *ctx, fz_stroke_state *shared);
/*
fz_unshare_stroke_state_with_dash_len: Given a reference to a
(possibly) shared stroke_state structure, return a reference
to a stroke_state structure (with room for a given amount of
dash data) that is guaranteed to be unshared (i.e. one that
can safely be modified).
shared: The reference to a (possibly) shared structure
to unshare. Ownership of this reference is passed in
to this function, even in the case of exceptions being
thrown.
Exceptions may be thrown in the event of failure to
allocate if required.
*/
fz_stroke_state *fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared, int len);
/*
fz_clone_stroke_state: Create an identical stroke_state
structure and return a reference to it.
stroke: The stroke state reference to clone.
Exceptions may be thrown in the event of a failure to
allocate.
*/
fz_stroke_state *fz_clone_stroke_state(fz_context *ctx, fz_stroke_state *stroke);
#endif

@ -0,0 +1,426 @@
#ifndef MUPDF_FITZ_PIXMAP_H
#define MUPDF_FITZ_PIXMAP_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/colorspace.h"
#include "mupdf/fitz/separation.h"
/*
Pixmaps represent a set of pixels for a 2 dimensional region of a
plane. Each pixel has n components per pixel, the last of which is
always alpha. The data is in premultiplied alpha when rendering, but
non-premultiplied for colorspace conversions and rescaling.
*/
typedef struct fz_pixmap_s fz_pixmap;
typedef struct fz_overprint_s fz_overprint;
/*
fz_pixmap_bbox: Return the bounding box for a pixmap.
*/
fz_irect *fz_pixmap_bbox(fz_context *ctx, const fz_pixmap *pix, fz_irect *bbox);
/*
fz_pixmap_width: Return the width of the pixmap in pixels.
*/
int fz_pixmap_width(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_height: Return the height of the pixmap in pixels.
*/
int fz_pixmap_height(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_x: Return the x value of the pixmap in pixels.
*/
int fz_pixmap_x(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_y: Return the y value of the pixmap in pixels.
*/
int fz_pixmap_y(fz_context *ctx, fz_pixmap *pix);
/*
fz_new_pixmap: Create a new pixmap, with its origin at (0,0)
cs: The colorspace to use for the pixmap, or NULL for an alpha
plane/mask.
w: The width of the pixmap (in pixels)
h: The height of the pixmap (in pixels)
seps: Details of separations.
alpha: 0 for no alpha, 1 for alpha.
Returns a pointer to the new pixmap. Throws exception on failure to
allocate.
*/
fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h, fz_separations *seps, int alpha);
/*
fz_new_pixmap_with_bbox: Create a pixmap of a given size,
location and pixel format.
The bounding box specifies the size of the created pixmap and
where it will be located. The colorspace determines the number
of components per pixel. Alpha is always present. Pixmaps are
reference counted, so drop references using fz_drop_pixmap.
colorspace: Colorspace format used for the created pixmap. The
pixmap will keep a reference to the colorspace.
bbox: Bounding box specifying location/size of created pixmap.
seps: Details of separations.
alpha: 0 for no alpha, 1 for alpha.
Returns a pointer to the new pixmap. Throws exception on failure to
allocate.
*/
fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *bbox, fz_separations *seps, int alpha);
/*
fz_new_pixmap_with_data: Create a new pixmap, with its origin at
(0,0) using the supplied data block.
cs: The colorspace to use for the pixmap, or NULL for an alpha
plane/mask.
w: The width of the pixmap (in pixels)
h: The height of the pixmap (in pixels)
seps: Details of separations.
alpha: 0 for no alpha, 1 for alpha.
stride: The byte offset from the pixel data in a row to the pixel
data in the next row.
samples: The data block to keep the samples in.
Returns a pointer to the new pixmap. Throws exception on failure to
allocate.
*/
fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, fz_separations *seps, int alpha, int stride, unsigned char *samples);
/*
fz_new_pixmap_with_bbox_and_data: Create a pixmap of a given size,
location and pixel format, using the supplied data block.
The bounding box specifies the size of the created pixmap and
where it will be located. The colorspace determines the number
of components per pixel. Alpha is always present. Pixmaps are
reference counted, so drop references using fz_drop_pixmap.
colorspace: Colorspace format used for the created pixmap. The
pixmap will keep a reference to the colorspace.
rect: Bounding box specifying location/size of created pixmap.
seps: Details of separations.
alpha: Number of alpha planes (0 or 1).
samples: The data block to keep the samples in.
Returns a pointer to the new pixmap. Throws exception on failure to
allocate.
*/
fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *rect, fz_separations *seps, int alpha, unsigned char *samples);
/*
fz_new_pixmap_from_pixmap: Create a new pixmap that represents
a subarea of the specified pixmap. A reference is taken to his
pixmap that will be dropped on destruction.
The supplied rectangle must be wholly contained within the original
pixmap.
Returns a pointer to the new pixmap. Throws exception on failure to
allocate.
*/
fz_pixmap *fz_new_pixmap_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, const fz_irect *rect);
/*
fz_keep_pixmap: Take a reference to a pixmap.
pix: The pixmap to increment the reference for.
Returns pix.
*/
fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix);
/*
fz_drop_pixmap: Drop a reference and free a pixmap.
Decrement the reference count for the pixmap. When no
references remain the pixmap will be freed.
*/
void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_colorspace: Return the colorspace of a pixmap
Returns colorspace.
*/
fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_components: Return the number of components in a pixmap.
Returns the number of components (including spots and alpha).
*/
int fz_pixmap_components(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_colorants: Return the number of colorants in a pixmap.
Returns the number of colorants (components, less any spots and alpha).
*/
int fz_pixmap_colorants(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_spots: Return the number of spots in a pixmap.
Returns the number of spots (components, less colorants and alpha). Does not throw exceptions.
*/
int fz_pixmap_spots(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_alpha: Return the number of alpha planes in a pixmap.
Returns the number of alphas. Does not throw exceptions.
*/
int fz_pixmap_alpha(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_samples: Returns a pointer to the pixel data of a pixmap.
Returns the pointer.
*/
unsigned char *fz_pixmap_samples(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_stride: Return the number of bytes in a row in the pixmap.
*/
int fz_pixmap_stride(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_set_resolution: Set the pixels per inch resolution of the pixmap.
*/
void fz_set_pixmap_resolution(fz_context *ctx, fz_pixmap *pix, int xres, int yres);
/*
fz_clear_pixmap_with_value: Clears a pixmap with the given value.
pix: The pixmap to clear.
value: Values in the range 0 to 255 are valid. Each component
sample for each pixel in the pixmap will be set to this value,
while alpha will always be set to 255 (non-transparent).
*/
void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value);
/*
Fill pixmap with solid color.
*/
void fz_fill_pixmap_with_color(fz_context *ctx, fz_pixmap *pix, fz_colorspace *colorspace, float *color, const fz_color_params *color_params);
/*
fz_clear_pixmap_with_value: Clears a subrect of a pixmap with the given value.
pix: The pixmap to clear.
value: Values in the range 0 to 255 are valid. Each component
sample for each pixel in the pixmap will be set to this value,
while alpha will always be set to 255 (non-transparent).
r: the rectangle.
*/
void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, const fz_irect *r);
/*
fz_clear_pixmap_with_value: Sets all components (including alpha) of
all pixels in a pixmap to 0.
pix: The pixmap to clear.
*/
void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix);
/*
fz_invert_pixmap: Invert all the pixels in a pixmap. All components
of all pixels are inverted (except alpha, which is unchanged).
*/
void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix);
/*
fz_tint_pixmap: Tint all the pixels in an RGB or Gray pixmap.
Multiplies all the samples with the input color argument.
r,g,b: The color to tint with, in 0 to 255 range.
*/
void fz_tint_pixmap(fz_context *ctx, fz_pixmap *pix, int r, int g, int b);
/*
fz_invert_pixmap: Invert all the pixels in a given rectangle of a
pixmap. All components of all pixels in the rectangle are inverted
(except alpha, which is unchanged).
*/
void fz_invert_pixmap_rect(fz_context *ctx, fz_pixmap *image, const fz_irect *rect);
/*
fz_gamma_pixmap: Apply gamma correction to a pixmap. All components
of all pixels are modified (except alpha, which is unchanged).
gamma: The gamma value to apply; 1.0 for no change.
*/
void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma);
/*
fz_unmultiply_pixmap: Convert a pixmap from premultiplied to
non-premultiplied format.
*/
void fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix);
/*
fz_convert_pixmap: Convert an existing pixmap to a desired
colorspace. Other properties of the pixmap, such as resolution
and position are copied to the converted pixmap.
pix: The pixmap to convert.
default_cs: If NULL pix->colorspace is used. It is possible that the data
may need to be interpreted as one of the color spaces in default_cs.
cs_des: Desired colorspace, may be NULL to denote alpha-only.
prf: Proofing color space through which we need to convert.
color_params: Parameters that may be used in conversion (e.g. ri).
keep_alpha: If 0 any alpha component is removed, otherwise
alpha is kept if present in the pixmap.
*/
fz_pixmap *fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *cs_des, fz_colorspace *prf, fz_default_colorspaces *default_cs, const fz_color_params *color_params, int keep_alpha);
/*
Pixmaps represent a set of pixels for a 2 dimensional region of a
plane. Each pixel has n components per pixel, the last of which is
always alpha. The data is in premultiplied alpha when rendering, but
non-premultiplied for colorspace conversions and rescaling.
x, y: The minimum x and y coord of the region in pixels.
w, h: The width and height of the region in pixels.
n: The number of color components in the image.
n = num composite colors + num spots + num alphas
s: The number of spot channels in the image.
alpha: 0 for no alpha, 1 for alpha present.
flags: flag bits.
Bit 0: If set, draw the image with linear interpolation.
Bit 1: If set, free the samples buffer when the pixmap
is destroyed.
stride: The byte offset from the data for any given pixel
to the data for the same pixel on the row below.
seps: NULL, or a pointer to a separations structure. If NULL,
s should be 0.
xres, yres: Image resolution in dpi. Default is 96 dpi.
colorspace: Pointer to a colorspace object describing the colorspace
the pixmap is in. If NULL, the image is a mask.
samples: A simple block of memory w * h * n bytes of memory in which
the components are stored. The first n bytes are components 0 to n-1
for the pixel at (x,y). Each successive n bytes gives another pixel
in scanline order. Subsequent scanlines follow on with no padding.
*/
struct fz_pixmap_s
{
fz_storable storable;
int x, y, w, h;
unsigned char n;
unsigned char s;
unsigned char alpha;
unsigned char flags;
ptrdiff_t stride;
fz_separations *seps;
int xres, yres;
fz_colorspace *colorspace;
unsigned char *samples;
fz_pixmap *underlying;
};
enum
{
FZ_PIXMAP_FLAG_INTERPOLATE = 1,
FZ_PIXMAP_FLAG_FREE_SAMPLES = 2
};
void fz_drop_pixmap_imp(fz_context *ctx, fz_storable *pix);
void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, const fz_irect *r, const fz_default_colorspaces *default_cs);
void fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix);
fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray);
size_t fz_pixmap_size(fz_context *ctx, fz_pixmap *pix);
fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_irect *clip);
typedef struct fz_scale_cache_s fz_scale_cache;
fz_scale_cache *fz_new_scale_cache(fz_context *ctx);
void fz_drop_scale_cache(fz_context *ctx, fz_scale_cache *cache);
fz_pixmap *fz_scale_pixmap_cached(fz_context *ctx, const fz_pixmap *src, float x, float y, float w, float h, const fz_irect *clip, fz_scale_cache *cache_x, fz_scale_cache *cache_y);
void fz_subsample_pixmap(fz_context *ctx, fz_pixmap *tile, int factor);
fz_irect *fz_pixmap_bbox_no_ctx(const fz_pixmap *src, fz_irect *bbox);
void fz_decode_tile(fz_context *ctx, fz_pixmap *pix, const float *decode);
void fz_decode_indexed_tile(fz_context *ctx, fz_pixmap *pix, const float *decode, int maxval);
void fz_unpack_tile(fz_context *ctx, fz_pixmap *dst, unsigned char * restrict src, int n, int depth, size_t stride, int scale);
/*
fz_pixmap_converter: Color convert a pixmap. The passing of default_cs is needed due to the base cs of the image possibly
needing to be treated as being in one of the page default color spaces.
*/
typedef void (fz_pixmap_converter)(fz_context *ctx, fz_pixmap *dp, fz_pixmap *sp, fz_colorspace *prf, const fz_default_colorspaces *default_cs, const fz_color_params *color_params, int copy_spots);
fz_pixmap_converter *fz_lookup_pixmap_converter(fz_context *ctx, fz_colorspace *ds, fz_colorspace *ss);
/*
fz_md5_pixmap: Return the md5 digest for a pixmap
*/
void fz_md5_pixmap(fz_context *ctx, fz_pixmap *pixmap, unsigned char digest[16]);
fz_pixmap *fz_new_pixmap_from_8bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span);
fz_pixmap *fz_new_pixmap_from_1bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span);
#ifdef HAVE_VALGRIND
int fz_valgrind_pixmap(const fz_pixmap *pix);
#else
#define fz_valgrind_pixmap(pix) do {} while (0)
#endif
/*
fz_clone_pixmap_area_with_different_seps: Convert between
different separation results.
*/
fz_pixmap *fz_clone_pixmap_area_with_different_seps(fz_context *ctx, fz_pixmap *src, const fz_irect *bbox, fz_colorspace *dcs, fz_separations *seps, const fz_color_params *color_params, fz_default_colorspaces *default_cs);
fz_pixmap *fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src, const fz_color_params *color_params, fz_colorspace *prf, fz_default_colorspaces *default_cs);
#endif

@ -0,0 +1,14 @@
#ifndef MUPDF_FITZ_POOL_H
#define MUPDF_FITZ_POOL_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
typedef struct fz_pool_s fz_pool;
fz_pool *fz_new_pool(fz_context *ctx);
void *fz_pool_alloc(fz_context *ctx, fz_pool *pool, size_t size);
char *fz_pool_strdup(fz_context *ctx, fz_pool *pool, const char *s);
void fz_drop_pool(fz_context *ctx, fz_pool *pool);
#endif

@ -0,0 +1,84 @@
#ifndef MUPDF_FITZ_SEPARATION_H
#define MUPDF_FITZ_SEPARATION_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
/*
A fz_separation structure holds details of a set of separations
(such as might be used on within a page of the document).
The app might control the separations by enabling/disabling them,
and subsequent renders would take this into account.
*/
enum
{
FZ_MAX_SEPARATIONS = 64
};
typedef struct fz_separations_s fz_separations;
typedef enum
{
/* "Composite" separations are rendered using process
* colors using the equivalent colors */
FZ_SEPARATION_COMPOSITE = 0,
/* Spot colors are rendered into their own spot plane. */
FZ_SEPARATION_SPOT = 1,
/* Disabled colors are not rendered at all in the final
* output. */
FZ_SEPARATION_DISABLED = 2
} fz_separation_behavior;
/* Create a new separations structure (initially empty) */
fz_separations *fz_new_separations(fz_context *ctx, int controllable);
/* Keep a reference */
fz_separations *fz_keep_separations(fz_context *ctx, fz_separations *sep);
/* Drop a reference */
void fz_drop_separations(fz_context *ctx, fz_separations *sep);
/* Add a separation (null terminated name, colorspace) */
void fz_add_separation(fz_context *ctx, fz_separations *sep, const char *name, fz_colorspace *cs, int cs_channel);
/* Add a separation with equivalents (null terminated name, colorspace) (old, deprecated) */
void fz_add_separation_equivalents(fz_context *ctx, fz_separations *sep, uint32_t rgba, uint32_t cmyk, const char *name);
/* Control the rendering of a given separation */
void fz_set_separation_behavior(fz_context *ctx, fz_separations *sep, int separation, fz_separation_behavior behavior);
/* Test for the current behavior of a separation */
fz_separation_behavior fz_separation_current_behavior(fz_context *ctx, const fz_separations *sep, int separation);
/* Quick test for all separations composite (the common case) */
int fz_separations_all_composite(fz_context *ctx, const fz_separations *sep);
/* Read separation name */
const char *fz_separation_name(fz_context *ctx, const fz_separations *sep, int separation);
/* Count the number of separations */
int fz_count_separations(fz_context *ctx, const fz_separations *sep);
/* Find out if separations are controllable. */
int fz_separations_controllable(fz_context *ctx, const fz_separations *seps);
/* Return the number of active separations. */
int fz_count_active_separations(fz_context *ctx, const fz_separations *seps);
/* Return a separations object with all the spots in the input
* separations object that are set to composite, reset to be
* enabled. If there ARE no spots in the object, this returns
* NULL. If the object already has all its spots enabled, then
* just returns another handle on the same object. */
fz_separations *fz_clone_separations_for_overprint(fz_context *ctx, fz_separations *seps);
/* Convert a color given in terms of one colorspace,
* to a color in terms of another colorspace/separations. */
void fz_convert_separation_colors(fz_context *ctx, const fz_color_params *color_params, const fz_colorspace *dst_cs, const fz_separations *dst_sep, float *dst_color, const fz_colorspace *src_cs, const float *src_color);
/* Get the equivalent separation color in a given colorspace. */
void fz_separation_equivalent(fz_context *ctx, const fz_separations *seps, int i, const fz_color_params *color_params, const fz_colorspace *dst_cs, const fz_colorspace *prf, float *convert);
#endif

@ -0,0 +1,202 @@
#ifndef MUPDF_FITZ_SHADE_H
#define MUPDF_FITZ_SHADE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/colorspace.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/compressed-buffer.h"
/*
* The shading code uses gouraud shaded triangle meshes.
*/
enum
{
FZ_FUNCTION_BASED = 1,
FZ_LINEAR = 2,
FZ_RADIAL = 3,
FZ_MESH_TYPE4 = 4,
FZ_MESH_TYPE5 = 5,
FZ_MESH_TYPE6 = 6,
FZ_MESH_TYPE7 = 7
};
/*
Structure is public to allow derived classes. Do not
access the members directly.
*/
typedef struct fz_shade_s
{
fz_storable storable;
fz_rect bbox; /* can be fz_infinite_rect */
fz_colorspace *colorspace;
fz_matrix matrix; /* matrix from pattern dict */
int use_background; /* background color for fills but not 'sh' */
float background[FZ_MAX_COLORS];
/* Just to be confusing, PDF Shadings of Type 1 (Function Based
* Shadings), do NOT use_function, but all the others do. This
* is because Type 1 shadings take 2 inputs, whereas all the
* others (when used with a function take 1 input. The type 1
* data is in the 'f' field of the union below. */
int use_function;
float function[256][FZ_MAX_COLORS + 1];
int type; /* function, linear, radial, mesh */
union
{
struct
{
int extend[2];
float coords[2][3]; /* (x,y,r) twice */
} l_or_r;
struct
{
int vprow;
int bpflag;
int bpcoord;
int bpcomp;
float x0, x1;
float y0, y1;
float c0[FZ_MAX_COLORS];
float c1[FZ_MAX_COLORS];
} m;
struct
{
fz_matrix matrix;
int xdivs;
int ydivs;
float domain[2][2];
float *fn_vals;
} f;
} u;
fz_compressed_buffer *buffer;
} fz_shade;
/*
fz_keep_shade: Add a reference to a fz_shade.
shade: The reference to keep.
Returns shade.
*/
fz_shade *fz_keep_shade(fz_context *ctx, fz_shade *shade);
/*
fz_drop_shade: Drop a reference to a fz_shade.
shade: The reference to drop. If this is the last
reference, shade will be destroyed.
*/
void fz_drop_shade(fz_context *ctx, fz_shade *shade);
/*
fz_drop_shade_imp: Internal function to destroy a
shade. Only exposed for use with the fz_store.
shade: The reference to destroy.
*/
void fz_drop_shade_imp(fz_context *ctx, fz_storable *shade);
/*
fz_bound_shade: Bound a given shading.
shade: The shade to bound.
ctm: The transform to apply to the shade before bounding.
r: Pointer to storage to put the bounds in.
Returns r, updated to contain the bounds for the shading.
*/
fz_rect *fz_bound_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_rect *r);
/*
fz_paint_shade: Render a shade to a given pixmap.
shade: The shade to paint.
override_cs: NULL, or colorspace to override the shades
inbuilt colorspace.
ctm: The transform to apply.
dest: The pixmap to render into.
color_params: The color rendering settings
bbox: Pointer to a bounding box to limit the rendering
of the shade.
op: NULL, or pointer to overprint bitmap.
*/
void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_colorspace *override_cs, const fz_matrix *ctm, fz_pixmap *dest, const fz_color_params *color_params, const fz_irect *bbox, const fz_overprint *op);
/*
* Handy routine for processing mesh based shades
*/
typedef struct fz_vertex_s fz_vertex;
struct fz_vertex_s
{
fz_point p;
float c[FZ_MAX_COLORS];
};
/*
fz_shade_prepare_fn: Callback function type for use with
fz_process_shade.
arg: Opaque pointer from fz_process_shade caller.
v: Pointer to a fz_vertex structure to populate.
c: Pointer to an array of floats used to populate v.
*/
typedef void (fz_shade_prepare_fn)(fz_context *ctx, void *arg, fz_vertex *v, const float *c);
/*
fz_shade_process_fn: Callback function type for use with
fz_process_shade.
arg: Opaque pointer from fz_process_shade caller.
av, bv, cv: Pointers to a fz_vertex structure describing
the corner locations and colors of a triangle to be
filled.
*/
typedef void (fz_shade_process_fn)(fz_context *ctx, void *arg, fz_vertex *av, fz_vertex *bv, fz_vertex *cv);
/*
fz_process_shade: Process a shade, using supplied callback
functions. This decomposes the shading to a mesh (even ones
that are not natively meshes, such as linear or radial
shadings), and processes triangles from those meshes.
shade: The shade to process.
ctm: The transform to use
prepare: Callback function to 'prepare' each vertex.
This function is passed an array of floats, and populates
a fz_vertex structure.
process: This function is passed 3 pointers to vertex
structures, and actually performs the processing (typically
filling the area between the vertexes).
process_arg: An opaque argument passed through from caller
to callback functions.
*/
void fz_process_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm,
fz_shade_prepare_fn *prepare,
fz_shade_process_fn *process,
void *process_arg);
#endif

@ -0,0 +1,306 @@
#ifndef MUPDF_FITZ_STORE_H
#define MUPDF_FITZ_STORE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
/*
Resource store
MuPDF stores decoded "objects" into a store for potential reuse.
If the size of the store gets too big, objects stored within it can
be evicted and freed to recover space. When MuPDF comes to decode
such an object, it will check to see if a version of this object is
already in the store - if it is, it will simply reuse it. If not, it
will decode it and place it into the store.
All objects that can be placed into the store are derived from the
fz_storable type (i.e. this should be the first component of the
objects structure). This allows for consistent (thread safe)
reference counting, and includes a function that will be called to
free the object as soon as the reference count reaches zero.
Most objects offer fz_keep_XXXX/fz_drop_XXXX functions derived
from fz_keep_storable/fz_drop_storable. Creation of such objects
includes a call to FZ_INIT_STORABLE to set up the fz_storable header.
*/
typedef struct fz_storable_s fz_storable;
typedef struct fz_key_storable_s fz_key_storable;
typedef void (fz_store_drop_fn)(fz_context *, fz_storable *);
struct fz_storable_s {
int refs;
fz_store_drop_fn *drop;
};
struct fz_key_storable_s {
fz_storable storable;
short store_key_refs;
};
#define FZ_INIT_STORABLE(S_,RC,DROP) \
do { fz_storable *S = &(S_)->storable; S->refs = (RC); \
S->drop = (DROP); \
} while (0)
#define FZ_INIT_KEY_STORABLE(KS_,RC,DROP) \
do { fz_key_storable *KS = &(KS_)->key_storable; KS->store_key_refs = 0;\
FZ_INIT_STORABLE(KS,RC,DROP); \
} while (0)
void *fz_keep_storable(fz_context *, const fz_storable *);
void fz_drop_storable(fz_context *, const fz_storable *);
void *fz_keep_key_storable(fz_context *, const fz_key_storable *);
void fz_drop_key_storable(fz_context *, const fz_key_storable *);
void *fz_keep_key_storable_key(fz_context *, const fz_key_storable *);
void fz_drop_key_storable_key(fz_context *, const fz_key_storable *);
/*
The store can be seen as a dictionary that maps keys to fz_storable
values. In order to allow keys of different types to be stored, we
have a structure full of functions for each key 'type'; this
fz_store_type pointer is stored with each key, and tells the store
how to perform certain operations (like taking/dropping a reference,
comparing two keys, outputting details for debugging etc).
The store uses a hash table internally for speed where possible. In
order for this to work, we need a mechanism for turning a generic
'key' into 'a hashable string'. For this purpose the type structure
contains a make_hash_key function pointer that maps from a void *
to a fz_store_hash structure. If make_hash_key function returns 0,
then the key is determined not to be hashable, and the value is
not stored in the hash table.
Some objects can be used both as values within the store, and as a
component of keys within the store. We refer to these objects as
"key storable" objects. In this case, we need to take additional
care to ensure that we do not end up keeping an item within the
store, purely because its value is referred to by another key in
the store.
An example of this are fz_images in PDF files. Each fz_image is
placed into the store to enable it to be easily reused. When the
image is rendered, a pixmap is generated from the image, and the
pixmap is placed into the store so it can be reused on subsequent
renders. The image forms part of the key for the pixmap.
When we close the pdf document (and any associated pages/display
lists etc), we drop the images from the store. This may leave us
in the position of the images having non-zero reference counts
purely because they are used as part of the keys for the pixmaps.
We therefore use special reference counting functions to keep
track of these "key storable" items, and hence store the number of
references to these items that are used in keys.
When the number of references to an object == the number of
references to an object from keys in the store, we know that we can
remove all the items which have that object as part of the key.
This is done by running a pass over the store, 'reaping' those
items.
Reap passes are slower than we would like as they touch every
item in the store. We therefore provide a way to 'batch' such
reap passes together, using fz_defer_reap_start/fz_defer_reap_end
to bracket a region in which many may be triggered.
*/
typedef struct fz_store_hash_s
{
fz_store_drop_fn *drop;
union
{
struct
{
const void *ptr;
int i;
} pi; /* 8 or 12 bytes */
struct
{
const void *ptr;
int i;
fz_irect r;
} pir; /* 24 or 28 bytes */
struct
{
int id;
float m[4];
void *ptr;
} im; /* 20 bytes */
struct
{
unsigned char src_md5[16];
unsigned char dst_md5[16];
unsigned int ri:2;
unsigned int bp:1;
unsigned int bpp16:1;
unsigned int proof:1;
unsigned int src_extras:5;
unsigned int dst_extras:5;
unsigned int copy_spots:1;
} link; /* 36 bytes */
} u;
} fz_store_hash; /* 40 or 44 bytes */
typedef struct fz_store_type_s
{
int (*make_hash_key)(fz_context *ctx, fz_store_hash *hash, void *key);
void *(*keep_key)(fz_context *ctx, void *key);
void (*drop_key)(fz_context *ctx, void *key);
int (*cmp_key)(fz_context *ctx, void *a, void *b);
void (*format_key)(fz_context *ctx, char *buf, int size, void *key);
int (*needs_reap)(fz_context *ctx, void *key);
} fz_store_type;
/*
fz_store_new_context: Create a new store inside the context
max: The maximum size (in bytes) that the store is allowed to grow
to. FZ_STORE_UNLIMITED means no limit.
*/
void fz_new_store_context(fz_context *ctx, size_t max);
/*
fz_drop_store_context: Drop a reference to the store.
*/
void fz_drop_store_context(fz_context *ctx);
/*
fz_keep_store_context: Take a reference to the store.
*/
fz_store *fz_keep_store_context(fz_context *ctx);
/*
fz_store_item: Add an item to the store.
Add an item into the store, returning NULL for success. If an item
with the same key is found in the store, then our item will not be
inserted, and the function will return a pointer to that value
instead. This function takes its own reference to val, as required
(i.e. the caller maintains ownership of its own reference).
key: The key used to index the item.
val: The value to store.
itemsize: The size in bytes of the value (as counted towards the
store size).
type: Functions used to manipulate the key.
*/
void *fz_store_item(fz_context *ctx, void *key, void *val, size_t itemsize, const fz_store_type *type);
/*
fz_find_item: Find an item within the store.
drop: The function used to free the value (to ensure we get a value
of the correct type).
key: The key used to index the item.
type: Functions used to manipulate the key.
Returns NULL for not found, otherwise returns a pointer to the value
indexed by key to which a reference has been taken.
*/
void *fz_find_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, const fz_store_type *type);
/*
fz_remove_item: Remove an item from the store.
If an item indexed by the given key exists in the store, remove it.
drop: The function used to free the value (to ensure we get a value
of the correct type).
key: The key used to find the item to remove.
type: Functions used to manipulate the key.
*/
void fz_remove_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, const fz_store_type *type);
/*
fz_empty_store: Evict everything from the store.
*/
void fz_empty_store(fz_context *ctx);
/*
fz_store_scavenge: Internal function used as part of the scavenging
allocator; when we fail to allocate memory, before returning a
failure to the caller, we try to scavenge space within the store by
evicting at least 'size' bytes. The allocator then retries.
size: The number of bytes we are trying to have free.
phase: What phase of the scavenge we are in. Updated on exit.
Returns non zero if we managed to free any memory.
*/
int fz_store_scavenge(fz_context *ctx, size_t size, int *phase);
/*
fz_store_scavenge_external: External function for callers to use
to scavenge while trying allocations.
size: The number of bytes we are trying to have free.
phase: What phase of the scavenge we are in. Updated on exit.
Returns non zero if we managed to free any memory.
*/
int fz_store_scavenge_external(fz_context *ctx, size_t size, int *phase);
/*
fz_shrink_store: Evict items from the store until the total size of
the objects in the store is reduced to a given percentage of its
current size.
percent: %age of current size to reduce the store to.
Returns non zero if we managed to free enough memory, zero otherwise.
*/
int fz_shrink_store(fz_context *ctx, unsigned int percent);
typedef int (fz_store_filter_fn)(fz_context *ctx, void *arg, void *key);
void fz_filter_store(fz_context *ctx, fz_store_filter_fn *fn, void *arg, const fz_store_type *type);
/*
fz_debug_store: Dump the contents of the store for debugging.
*/
void fz_debug_store(fz_context *ctx);
/*
fz_defer_reap_start: Increment the defer reap count.
No reap operations will take place (except for those
triggered by an immediate failed malloc) until the
defer reap count returns to 0.
Call this at the start of a process during which you
potentially might drop many reapable objects.
It is vital that every fz_defer_reap_start is matched
by a fz_defer_reap_end call.
*/
void fz_defer_reap_start(fz_context *ctx);
/*
fz_defer_reap_end: Decrement the defer reap count.
If the defer reap count returns to 0, and the store
has reapable objects in, a reap pass will begin.
Call this at the end of a process during which you
potentially might drop many reapable objects.
It is vital that every fz_defer_reap_start is matched
by a fz_defer_reap_end call.
*/
void fz_defer_reap_end(fz_context *ctx);
#endif

@ -0,0 +1,553 @@
#ifndef MUPDF_FITZ_STREAM_H
#define MUPDF_FITZ_STREAM_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
/*
fz_file_exists: Return true if the named file exists and is readable.
*/
int fz_file_exists(fz_context *ctx, const char *path);
/*
fz_stream is a buffered reader capable of seeking in both
directions.
Streams are reference counted, so references must be dropped
by a call to fz_drop_stream.
Only the data between rp and wp is valid.
*/
typedef struct fz_stream_s fz_stream;
/*
fz_open_file: Open the named file and wrap it in a stream.
filename: Path to a file. On non-Windows machines the filename should
be exactly as it would be passed to fopen(2). On Windows machines, the
path should be UTF-8 encoded so that non-ASCII characters can be
represented. Other platforms do the encoding as standard anyway (and
in most cases, particularly for MacOS and Linux, the encoding they
use is UTF-8 anyway).
*/
fz_stream *fz_open_file(fz_context *ctx, const char *filename);
fz_stream *fz_open_file_progressive(fz_context *ctx, const char *filename, int bps);
/*
fz_open_file_w: Open the named file and wrap it in a stream.
This function is only available when compiling for Win32.
filename: Wide character path to the file as it would be given
to _wfopen().
*/
fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename);
/*
fz_open_memory: Open a block of memory as a stream.
data: Pointer to start of data block. Ownership of the data block is
NOT passed in.
len: Number of bytes in data block.
Returns pointer to newly created stream. May throw exceptions on
failure to allocate.
*/
fz_stream *fz_open_memory(fz_context *ctx, const unsigned char *data, size_t len);
/*
fz_open_buffer: Open a buffer as a stream.
buf: The buffer to open. Ownership of the buffer is NOT passed in
(this function takes its own reference).
Returns pointer to newly created stream. May throw exceptions on
failure to allocate.
*/
fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf);
/*
fz_open_leecher: Attach a filter to a stream that will store any
characters read from the stream into the supplied buffer.
chain: The underlying stream to leech from.
buf: The buffer into which the read data should be appended.
The buffer will be resized as required.
Returns pointer to newly created stream. May throw exceptions on
failure to allocate.
*/
fz_stream *fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buf);
/*
fz_drop_stream: Close an open stream.
Drops a reference for the stream. Once no references remain
the stream will be closed, as will any file descriptor the
stream is using.
*/
void fz_drop_stream(fz_context *ctx, fz_stream *stm);
/*
fz_tell: return the current reading position within a stream
*/
int64_t fz_tell(fz_context *ctx, fz_stream *stm);
/*
fz_seek: Seek within a stream.
stm: The stream to seek within.
offset: The offset to seek to.
whence: From where the offset is measured (see fseek).
*/
void fz_seek(fz_context *ctx, fz_stream *stm, int64_t offset, int whence);
/*
fz_read: Read from a stream into a given data block.
stm: The stream to read from.
data: The data block to read into.
len: The length of the data block (in bytes).
Returns the number of bytes read. May throw exceptions.
*/
size_t fz_read(fz_context *ctx, fz_stream *stm, unsigned char *data, size_t len);
/*
fz_skip: Read from a stream discarding data.
stm: The stream to read from.
len: The number of bytes to read.
Returns the number of bytes read. May throw exceptions.
*/
size_t fz_skip(fz_context *ctx, fz_stream *stm, size_t len);
/*
fz_read_all: Read all of a stream into a buffer.
stm: The stream to read from
initial: Suggested initial size for the buffer.
Returns a buffer created from reading from the stream. May throw
exceptions on failure to allocate.
*/
fz_buffer *fz_read_all(fz_context *ctx, fz_stream *stm, size_t initial);
/*
fz_read_file: Read all the contents of a file into a buffer.
*/
fz_buffer *fz_read_file(fz_context *ctx, const char *filename);
/*
fz_read_[u]int(16|24|32|64)(_le)?
Read a 16/32/64 bit signed/unsigned integer from stream,
in big or little-endian byte orders.
Throws an exception if EOF is encountered.
*/
uint16_t fz_read_uint16(fz_context *ctx, fz_stream *stm);
uint32_t fz_read_uint24(fz_context *ctx, fz_stream *stm);
uint32_t fz_read_uint32(fz_context *ctx, fz_stream *stm);
uint64_t fz_read_uint64(fz_context *ctx, fz_stream *stm);
uint16_t fz_read_uint16_le(fz_context *ctx, fz_stream *stm);
uint32_t fz_read_uint24_le(fz_context *ctx, fz_stream *stm);
uint32_t fz_read_uint32_le(fz_context *ctx, fz_stream *stm);
uint64_t fz_read_uint64_le(fz_context *ctx, fz_stream *stm);
int16_t fz_read_int16(fz_context *ctx, fz_stream *stm);
int32_t fz_read_int32(fz_context *ctx, fz_stream *stm);
int64_t fz_read_int64(fz_context *ctx, fz_stream *stm);
int16_t fz_read_int16_le(fz_context *ctx, fz_stream *stm);
int32_t fz_read_int32_le(fz_context *ctx, fz_stream *stm);
int64_t fz_read_int64_le(fz_context *ctx, fz_stream *stm);
/*
fz_read_string: Read a null terminated string from the stream into
a buffer of a given length. The buffer will be null terminated.
Throws on failure (including the failure to fit the entire string
including the terminator into the buffer).
*/
void fz_read_string(fz_context *ctx, fz_stream *stm, char *buffer, int len);
enum
{
FZ_STREAM_META_PROGRESSIVE = 1,
FZ_STREAM_META_LENGTH = 2
};
/*
fz_stream_meta: Perform a meta call on a stream (typically to
request meta information about a stream).
stm: The stream to query.
key: The meta request identifier.
size: Meta request specific parameter - typically the size of
the data block pointed to by ptr.
ptr: Meta request specific parameter - typically a pointer to
a block of data to be filled in.
Returns -1 if this stream does not support this meta operation,
or a meta operation specific return value.
*/
int fz_stream_meta(fz_context *ctx, fz_stream *stm, int key, int size, void *ptr);
/*
fz_stream_next_fn: A function type for use when implementing
fz_streams. The supplied function of this type is called
whenever data is required, and the current buffer is empty.
stm: The stream to operate on.
max: a hint as to the maximum number of bytes that the caller
needs to be ready immediately. Can safely be ignored.
Returns -1 if there is no more data in the stream. Otherwise,
the function should find its internal state using stm->state,
refill its buffer, update stm->rp and stm->wp to point to the
start and end of the new data respectively, and then
"return *stm->rp++".
*/
typedef int (fz_stream_next_fn)(fz_context *ctx, fz_stream *stm, size_t max);
/*
fz_stream_drop_fn: A function type for use when implementing
fz_streams. The supplied function of this type is called
when the stream is dropped, to release the stream specific
state information.
state: The stream state to release.
*/
typedef void (fz_stream_drop_fn)(fz_context *ctx, void *state);
/*
fz_stream_seek_fn: A function type for use when implementing
fz_streams. The supplied function of this type is called when
fz_seek is requested, and the arguments are as defined for
fz_seek.
The stream can find it's private state in stm->state.
*/
typedef void (fz_stream_seek_fn)(fz_context *ctx, fz_stream *stm, int64_t offset, int whence);
/*
fz_stream_meta_fn: A function type for use when implementing
fz_streams. The supplied function of this type is called when
fz_meta is requested, and the arguments are as defined for
fz_meta.
The stream can find it's private state in stm->state.
*/
typedef int (fz_stream_meta_fn)(fz_context *ctx, fz_stream *stm, int key, int size, void *ptr);
struct fz_stream_s
{
int refs;
int error;
int eof;
int64_t pos;
int avail;
int bits;
unsigned char *rp, *wp;
void *state;
fz_stream_next_fn *next;
fz_stream_drop_fn *drop;
fz_stream_seek_fn *seek;
fz_stream_meta_fn *meta;
};
/*
fz_new_stream: Create a new stream object with the given
internal state and function pointers.
state: Internal state (opaque to everything but implementation).
next: Should provide the next set of bytes (up to max) of stream
data. Return the number of bytes read, or EOF when there is no
more data.
drop: Should clean up and free the internal state. May not
throw exceptions.
*/
fz_stream *fz_new_stream(fz_context *ctx, void *state, fz_stream_next_fn *next, fz_stream_drop_fn *drop);
fz_stream *fz_keep_stream(fz_context *ctx, fz_stream *stm);
/*
fz_read_best: Attempt to read a stream into a buffer. If truncated
is NULL behaves as fz_read_all, sets a truncated flag in case of
error.
stm: The stream to read from.
initial: Suggested initial size for the buffer.
truncated: Flag to store success/failure indication in.
Returns a buffer created from reading from the stream.
*/
fz_buffer *fz_read_best(fz_context *ctx, fz_stream *stm, size_t initial, int *truncated);
/*
fz_read_line: Read a line from stream into the buffer until either a
terminating newline or EOF, which it replaces with a null byte ('\0').
Returns buf on success, and NULL when end of file occurs while no characters
have been read.
*/
char *fz_read_line(fz_context *ctx, fz_stream *stm, char *buf, size_t max);
/*
fz_available: Ask how many bytes are available immediately from
a given stream.
stm: The stream to read from.
max: A hint for the underlying stream; the maximum number of
bytes that we are sure we will want to read. If you do not know
this number, give 1.
Returns the number of bytes immediately available between the
read and write pointers. This number is guaranteed only to be 0
if we have hit EOF. The number of bytes returned here need have
no relation to max (could be larger, could be smaller).
*/
static inline size_t fz_available(fz_context *ctx, fz_stream *stm, size_t max)
{
size_t len = stm->wp - stm->rp;
int c = EOF;
if (len)
return len;
if (stm->eof)
return 0;
fz_try(ctx)
c = stm->next(ctx, stm, max);
fz_catch(ctx)
{
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
fz_warn(ctx, "read error; treating as end of file");
stm->error = 1;
c = EOF;
}
if (c == EOF)
{
stm->eof = 1;
return 0;
}
stm->rp--;
return stm->wp - stm->rp;
}
/*
fz_read_byte: Read the next byte from a stream.
stm: The stream t read from.
Returns -1 for end of stream, or the next byte. May
throw exceptions.
*/
static inline int fz_read_byte(fz_context *ctx, fz_stream *stm)
{
int c = EOF;
if (stm->rp != stm->wp)
return *stm->rp++;
if (stm->eof)
return EOF;
fz_try(ctx)
c = stm->next(ctx, stm, 1);
fz_catch(ctx)
{
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
fz_warn(ctx, "read error; treating as end of file");
stm->error = 1;
c = EOF;
}
if (c == EOF)
stm->eof = 1;
return c;
}
/*
fz_peek_byte: Peek at the next byte in a stream.
stm: The stream to peek at.
Returns -1 for EOF, or the next byte that will be read.
*/
static inline int fz_peek_byte(fz_context *ctx, fz_stream *stm)
{
int c = EOF;
if (stm->rp != stm->wp)
return *stm->rp;
if (stm->eof)
return EOF;
fz_try(ctx)
{
c = stm->next(ctx, stm, 1);
if (c != EOF)
stm->rp--;
}
fz_catch(ctx)
{
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
fz_warn(ctx, "read error; treating as end of file");
stm->error = 1;
c = EOF;
}
if (c == EOF)
stm->eof = 1;
return c;
}
/*
fz_unread_byte: Unread the single last byte successfully
read from a stream. Do not call this without having
successfully read a byte.
stm: The stream to operate upon.
*/
static inline void fz_unread_byte(fz_context *ctx FZ_UNUSED, fz_stream *stm)
{
stm->rp--;
}
static inline int fz_is_eof(fz_context *ctx, fz_stream *stm)
{
if (stm->rp == stm->wp)
{
if (stm->eof)
return 1;
return fz_peek_byte(ctx, stm) == EOF;
}
return 0;
}
/*
fz_read_bits: Read the next n bits from a stream (assumed to
be packed most significant bit first).
stm: The stream to read from.
n: The number of bits to read, between 1 and 8*sizeof(int)
inclusive.
Returns -1 for EOF, or the required number of bits.
*/
static inline unsigned int fz_read_bits(fz_context *ctx, fz_stream *stm, int n)
{
int x;
if (n <= stm->avail)
{
stm->avail -= n;
x = (stm->bits >> stm->avail) & ((1 << n) - 1);
}
else
{
x = stm->bits & ((1 << stm->avail) - 1);
n -= stm->avail;
stm->avail = 0;
while (n > 8)
{
x = (x << 8) | fz_read_byte(ctx, stm);
n -= 8;
}
if (n > 0)
{
stm->bits = fz_read_byte(ctx, stm);
stm->avail = 8 - n;
x = (x << n) | (stm->bits >> stm->avail);
}
}
return x;
}
/*
fz_read_rbits: Read the next n bits from a stream (assumed to
be packed least significant bit first).
stm: The stream to read from.
n: The number of bits to read, between 1 and 8*sizeof(int)
inclusive.
Returns (unsigned int)-1 for EOF, or the required number of bits.
*/
static inline unsigned int fz_read_rbits(fz_context *ctx, fz_stream *stm, int n)
{
int x;
if (n <= stm->avail)
{
x = stm->bits & ((1 << n) - 1);
stm->avail -= n;
stm->bits = stm->bits >> n;
}
else
{
unsigned int used = 0;
x = stm->bits & ((1 << stm->avail) - 1);
n -= stm->avail;
used = stm->avail;
stm->avail = 0;
while (n > 8)
{
x = (fz_read_byte(ctx, stm) << used) | x;
n -= 8;
used += 8;
}
if (n > 0)
{
stm->bits = fz_read_byte(ctx, stm);
x = ((stm->bits & ((1 << n) - 1)) << used) | x;
stm->avail = 8 - n;
stm->bits = stm->bits >> n;
}
}
return x;
}
/*
fz_sync_bits: Called after reading bits to tell the stream
that we are about to return to reading bytewise. Resyncs
the stream to whole byte boundaries.
*/
static inline void fz_sync_bits(fz_context *ctx FZ_UNUSED, fz_stream *stm)
{
stm->avail = 0;
}
static inline int fz_is_eof_bits(fz_context *ctx, fz_stream *stm)
{
return fz_is_eof(ctx, stm) && (stm->avail == 0 || stm->bits == EOF);
}
#endif

@ -0,0 +1,166 @@
#ifndef MUPDF_FITZ_STRING_H
#define MUPDF_FITZ_STRING_H
#include "mupdf/fitz/system.h"
/* The Unicode character used to incoming character whose value is unknown or unrepresentable. */
#define FZ_REPLACEMENT_CHARACTER 0xFFFD
/*
Safe string functions
*/
/*
fz_strsep: Given a pointer to a C string (or a pointer to NULL) break
it at the first occurrence of a delimiter char (from a given set).
stringp: Pointer to a C string pointer (or NULL). Updated on exit to
point to the first char of the string after the delimiter that was
found. The string pointed to by stringp will be corrupted by this
call (as the found delimiter will be overwritten by 0).
delim: A C string of acceptable delimiter characters.
Returns a pointer to a C string containing the chars of stringp up
to the first delimiter char (or the end of the string), or NULL.
*/
char *fz_strsep(char **stringp, const char *delim);
/*
fz_strlcpy: Copy at most n-1 chars of a string into a destination
buffer with null termination, returning the real length of the
initial string (excluding terminator).
dst: Destination buffer, at least n bytes long.
src: C string (non-NULL).
n: Size of dst buffer in bytes.
Returns the length (excluding terminator) of src.
*/
size_t fz_strlcpy(char *dst, const char *src, size_t n);
/*
fz_strlcat: Concatenate 2 strings, with a maximum length.
dst: pointer to first string in a buffer of n bytes.
src: pointer to string to concatenate.
n: Size (in bytes) of buffer that dst is in.
Returns the real length that a concatenated dst + src would have been
(not including terminator).
*/
size_t fz_strlcat(char *dst, const char *src, size_t n);
/*
fz_dirname: extract the directory component from a path.
*/
void fz_dirname(char *dir, const char *path, size_t dirsize);
/*
fz_urldecode: decode url escapes.
*/
char *fz_urldecode(char *url);
/*
fz_format_output_path: create output file name using a template.
If the path contains %[0-9]*d, the first such pattern will be replaced
with the page number. If the template does not contain such a pattern, the page
number will be inserted before the file suffix. If the template does not have
a file suffix, the page number will be added to the end.
*/
void fz_format_output_path(fz_context *ctx, char *path, size_t size, const char *fmt, int page);
/*
fz_cleanname: rewrite path to the shortest string that names the same path.
Eliminates multiple and trailing slashes, interprets "." and "..".
Overwrites the string in place.
*/
char *fz_cleanname(char *name);
/*
Case insensitive (ASCII only) string comparison.
*/
int fz_strcasecmp(const char *a, const char *b);
/*
FZ_UTFMAX: Maximum number of bytes in a decoded rune (maximum length returned by fz_chartorune).
*/
enum { FZ_UTFMAX = 4 };
/*
fz_chartorune: UTF8 decode a single rune from a sequence of chars.
rune: Pointer to an int to assign the decoded 'rune' to.
str: Pointer to a UTF8 encoded string.
Returns the number of bytes consumed.
*/
int fz_chartorune(int *rune, const char *str);
/*
fz_runetochar: UTF8 encode a rune to a sequence of chars.
str: Pointer to a place to put the UTF8 encoded character.
rune: Pointer to a 'rune'.
Returns the number of bytes the rune took to output.
*/
int fz_runetochar(char *str, int rune);
/*
fz_runelen: Count how many chars are required to represent a rune.
rune: The rune to encode.
Returns the number of bytes required to represent this run in UTF8.
*/
int fz_runelen(int rune);
/*
fz_utflen: Count how many runes the UTF-8 encoded string
consists of.
s: The UTF-8 encoded, NUL-terminated text string.
Returns the number of runes in the string.
*/
int fz_utflen(const char *s);
/*
fz_strtof: Locale-independent decimal to binary
conversion. On overflow return (-)INFINITY and set errno to ERANGE. On
underflow return 0 and set errno to ERANGE. Special inputs (case
insensitive): "NAN", "INF" or "INFINITY".
*/
float fz_strtof(const char *s, char **es);
/*
fz_strtof_no_exp: Like fz_strtof, but does not recognize exponent
format. So fz_strtof_no_exp("1.5e20", &tail) will return 1.5 and tail
will point to "e20".
*/
float fz_strtof_no_exp(const char *string, char **tailptr);
/*
fz_grisu: Compute decimal integer m, exp such that:
f = m * 10^exp
m is as short as possible without losing exactness
Assumes special cases (0, NaN, +Inf, -Inf) have been handled.
*/
int fz_grisu(float f, char *s, int *exp);
/*
Check and parse string into page ranges:
( ','? ([0-9]+|'N') ( '-' ([0-9]+|N) )? )+
*/
int fz_is_page_range(fz_context *ctx, const char *s);
const char *fz_parse_page_range(fz_context *ctx, const char *s, int *a, int *b, int n);
#endif

@ -0,0 +1,197 @@
#ifndef MUPDF_FITZ_STRUCTURED_TEXT_H
#define MUPDF_FITZ_STRUCTURED_TEXT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/font.h"
#include "mupdf/fitz/colorspace.h"
#include "mupdf/fitz/image.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/device.h"
/*
Text extraction device: Used for searching, format conversion etc.
(In development - Subject to change in future versions)
*/
typedef struct fz_stext_char_s fz_stext_char;
typedef struct fz_stext_line_s fz_stext_line;
typedef struct fz_stext_block_s fz_stext_block;
typedef struct fz_stext_page_s fz_stext_page;
/*
FZ_STEXT_PRESERVE_LIGATURES: If this option is activated ligatures
are passed through to the application in their original form. If
this option is deactivated ligatures are expanded into their
constituent parts, e.g. the ligature ffi is expanded into three
separate characters f, f and i.
FZ_STEXT_PRESERVE_WHITESPACE: If this option is activated whitespace
is passed through to the application in its original form. If this
option is deactivated any type of horizontal whitespace (including
horizontal tabs) will be replaced with space characters of variable
width.
FZ_STEXT_PRESERVE_IMAGES: If this option is set, then images will
be stored in the structured text structure. The default is to ignore
all images.
*/
enum
{
FZ_STEXT_PRESERVE_LIGATURES = 1,
FZ_STEXT_PRESERVE_WHITESPACE = 2,
FZ_STEXT_PRESERVE_IMAGES = 4,
};
/*
A text page is a list of blocks, together with an overall bounding box.
*/
struct fz_stext_page_s
{
fz_pool *pool;
fz_rect mediabox;
fz_stext_block *first_block, *last_block;
};
enum
{
FZ_STEXT_BLOCK_TEXT = 0,
FZ_STEXT_BLOCK_IMAGE = 1
};
/*
A text block is a list of lines of text (typically a paragraph), or an image.
*/
struct fz_stext_block_s
{
int type;
fz_rect bbox;
union {
struct { fz_stext_line *first_line, *last_line; } t;
struct { fz_matrix transform; fz_image *image; } i;
} u;
fz_stext_block *prev, *next;
};
/*
A text line is a list of characters that share a common baseline.
*/
struct fz_stext_line_s
{
int wmode; /* 0 for horizontal, 1 for vertical */
fz_point dir; /* normalized direction of baseline */
fz_rect bbox;
fz_stext_char *first_char, *last_char;
fz_stext_line *prev, *next;
};
/*
A text char is a unicode character, the style in which is appears, and
the point at which it is positioned.
*/
struct fz_stext_char_s
{
int c;
fz_point origin;
fz_rect bbox;
float size;
fz_font *font;
fz_stext_char *next;
};
extern const char *fz_stext_options_usage;
int fz_stext_char_count(fz_context *ctx, fz_stext_page *page);
const fz_stext_char *fz_stext_char_at(fz_context *ctx, fz_stext_page *page, int idx);
/*
fz_new_stext_page: Create an empty text page.
The text page is filled out by the text device to contain the blocks
and lines of text on the page.
mediabox: optional mediabox information.
*/
fz_stext_page *fz_new_stext_page(fz_context *ctx, const fz_rect *mediabox);
void fz_drop_stext_page(fz_context *ctx, fz_stext_page *page);
/*
fz_print_stext_page_as_html: Output a page to a file in HTML (visual) format.
*/
void fz_print_stext_page_as_html(fz_context *ctx, fz_output *out, fz_stext_page *page);
void fz_print_stext_header_as_html(fz_context *ctx, fz_output *out);
void fz_print_stext_trailer_as_html(fz_context *ctx, fz_output *out);
/*
fz_print_stext_page_as_xhtml: Output a page to a file in XHTML (semantic) format.
*/
void fz_print_stext_page_as_xhtml(fz_context *ctx, fz_output *out, fz_stext_page *page);
void fz_print_stext_header_as_xhtml(fz_context *ctx, fz_output *out);
void fz_print_stext_trailer_as_xhtml(fz_context *ctx, fz_output *out);
/*
fz_print_stext_page_as_xml: Output a page to a file in XML format.
*/
void fz_print_stext_page_as_xml(fz_context *ctx, fz_output *out, fz_stext_page *page);
/*
fz_print_stext_page_as_text: Output a page to a file in UTF-8 format.
*/
void fz_print_stext_page_as_text(fz_context *ctx, fz_output *out, fz_stext_page *page);
/*
fz_search_stext_page: Search for occurrence of 'needle' in text page.
Return the number of hits and store hit bboxes in the passed in array.
NOTE: This is an experimental interface and subject to change without notice.
*/
int fz_search_stext_page(fz_context *ctx, fz_stext_page *text, const char *needle, fz_rect *hit_bbox, int hit_max);
/*
fz_highlight_selection: Return a list of rectangles to highlight lines inside the selection points.
*/
int fz_highlight_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_point b, fz_rect *hit_bbox, int hit_max);
/*
fz_copy_selection: Return a newly allocated UTF-8 string with the text for a given selection.
crlf: If true, write "\r\n" style line endings (otherwise "\n" only).
*/
char *fz_copy_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_point b, int crlf);
/*
struct fz_stext_options: Options for creating a pixmap and draw device.
*/
typedef struct fz_stext_options_s fz_stext_options;
struct fz_stext_options_s
{
int flags;
};
/*
fz_parse_stext_options: Parse stext device options from a comma separated key-value string.
*/
fz_stext_options *fz_parse_stext_options(fz_context *ctx, fz_stext_options *opts, const char *string);
/*
fz_new_stext_device: Create a device to extract the text on a page.
Gather the text on a page into blocks and lines.
The reading order is taken from the order the text is drawn in the
source file, so may not be accurate.
page: The text page to which content should be added. This will
usually be a newly created (empty) text page, but it can be one
containing data already (for example when merging multiple pages,
or watermarking).
options: Options to configure the stext device.
*/
fz_device *fz_new_stext_device(fz_context *ctx, fz_stext_page *page, const fz_stext_options *options);
#endif

@ -0,0 +1,363 @@
#ifndef MUPDF_FITZ_SYSTEM_H
#define MUPDF_FITZ_SYSTEM_H
/* Turn on valgrind pacification in debug builds. */
#ifndef NDEBUG
#ifndef PACIFY_VALGRIND
#define PACIFY_VALGRIND
#endif
#endif
/*
Include the standard libc headers.
*/
#include <stddef.h> /* needed for size_t */
#include <stdarg.h> /* needed for va_list vararg functions */
#include <setjmp.h> /* needed for the try/catch macros */
#if defined(_MSC_VER) && (_MSC_VER < 1700) /* MSVC older than VS2012 */
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#ifndef INT64_MAX
#define INT64_MAX 9223372036854775807i64
#endif
#else
#include <stdint.h> /* needed for int64_t */
#endif
#include "mupdf/memento.h"
#include "mupdf/fitz/track-usage.h"
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
#define FZ_PI 3.14159265f
#define FZ_RADIAN 57.2957795f
#define FZ_DEGREE 0.017453292f
#define FZ_SQRT2 1.41421356f
#define FZ_LN2 0.69314718f
/*
Spot architectures where we have optimisations.
*/
#if defined(__arm__) || defined(__thumb__)
#ifndef ARCH_ARM
#define ARCH_ARM
#endif
#endif
/*
Some differences in libc can be smoothed over
*/
#ifdef __APPLE__
#define HAVE_SIGSETJMP
#elif defined(__unix) && !defined(__NACL__)
#define HAVE_SIGSETJMP
#endif
/*
Where possible (i.e. on platforms on which they are provided), use
sigsetjmp/siglongjmp in preference to setjmp/longjmp. We don't alter
signal handlers within mupdf, so there is no need for us to
store/restore them - hence we use the non-restoring variants. This
makes a large speed difference on MacOSX (and probably other
platforms too.
*/
#ifdef HAVE_SIGSETJMP
#define fz_setjmp(BUF) sigsetjmp(BUF, 0)
#define fz_longjmp(BUF,VAL) siglongjmp(BUF, VAL)
#define fz_jmp_buf sigjmp_buf
#else
#define fz_setjmp(BUF) setjmp(BUF)
#define fz_longjmp(BUF,VAL) longjmp(BUF,VAL)
#define fz_jmp_buf jmp_buf
#endif
/* these constants mirror the corresponding macros in stdio.h */
#ifndef EOF
#define EOF (-1)
#endif
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
#ifdef _MSC_VER /* Microsoft Visual C */
/* MSVC up to VS2012 */
#if _MSC_VER < 1800
static __inline int signbit(double x)
{
union
{
double d;
__int64 i;
} u;
u.d = x;
return (int)(u.i>>63);
}
#endif
#pragma warning( disable: 4244 ) /* conversion from X to Y, possible loss of data */
#pragma warning( disable: 4701 ) /* Potentially uninitialized local variable 'name' used */
#pragma warning( disable: 4996 ) /* 'function': was declared deprecated */
#if _MSC_VER <= 1700 /* MSVC 2012 */
#define isnan(x) _isnan(x)
#define isinf(x) (!_finite(x))
#endif
#define hypotf _hypotf
#define atoll _atoi64
#endif
#ifdef _WIN32
char *fz_utf8_from_wchar(const wchar_t *s);
wchar_t *fz_wchar_from_utf8(const char *s);
/* really a FILE* but we don't want to include stdio.h here */
void *fz_fopen_utf8(const char *name, const char *mode);
int fz_remove_utf8(const char *name);
char **fz_argv_from_wargv(int argc, wchar_t **wargv);
void fz_free_argv(int argc, char **argv);
#endif
/* Cope with systems (such as Windows) with no S_ISDIR */
#ifndef S_ISDIR
#define S_ISDIR(mode) ((mode) & S_IFDIR)
#endif
/* inline is standard in C++. For some compilers we can enable it within C too. */
#ifndef __cplusplus
#if __STDC_VERSION__ == 199901L /* C99 */
#elif _MSC_VER >= 1500 /* MSVC 9 or newer */
#define inline __inline
#elif __GNUC__ >= 3 /* GCC 3 or newer */
#define inline __inline
#else /* Unknown or ancient */
#define inline
#endif
#endif
/* restrict is standard in C99, but not in all C++ compilers. */
#if __STDC_VERSION__ == 199901L /* C99 */
#elif _MSC_VER >= 1600 /* MSVC 10 or newer */
#define restrict __restrict
#elif __GNUC__ >= 3 /* GCC 3 or newer */
#define restrict __restrict
#else /* Unknown or ancient */
#define restrict
#endif
/* noreturn is a GCC extension */
#ifdef __GNUC__
#define FZ_NORETURN __attribute__((noreturn))
#else
#ifdef _MSC_VER
#define FZ_NORETURN __declspec(noreturn)
#else
#define FZ_NORETURN
#endif
#endif
/* Flag unused parameters, for use with 'static inline' functions in headers. */
#if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7
#define FZ_UNUSED __attribute__((__unused__))
#else
#define FZ_UNUSED
#endif
/* GCC can do type checking of printf strings */
#ifdef __printflike
#define FZ_PRINTFLIKE(F,V) __printflike(F,V)
#else
#if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7
#define FZ_PRINTFLIKE(F,V) __attribute__((__format__ (__printf__, F, V)))
#else
#define FZ_PRINTFLIKE(F,V)
#endif
#endif
/* ARM assembly specific defines */
#ifdef ARCH_ARM
/* If we're compiling as thumb code, then we need to tell the compiler
* to enter and exit ARM mode around our assembly sections. If we move
* the ARM functions to a separate file and arrange for it to be compiled
* without thumb mode, we can save some time on entry.
*/
/* This is slightly suboptimal; __thumb__ and __thumb2__ become defined
* and undefined by #pragma arm/#pragma thumb - but we can't define a
* macro to track that. */
#if defined(__thumb__) || defined(__thumb2__)
#define ENTER_ARM ".balign 4\nmov r12,pc\nbx r12\n0:.arm\n"
#define ENTER_THUMB "9:.thumb\n"
#else
#define ENTER_ARM
#define ENTER_THUMB
#endif
#endif
#ifdef CLUSTER
/* Include this first so our defines don't clash with the system definitions */
#include <math.h>
/*
* Trig functions
*/
static float
my_atan_table[258] =
{
0.0000000000f, 0.00390623013f,0.00781234106f,0.0117182136f,
0.0156237286f, 0.0195287670f, 0.0234332099f, 0.0273369383f,
0.0312398334f, 0.0351417768f, 0.0390426500f, 0.0429423347f,
0.0468407129f, 0.0507376669f, 0.0546330792f, 0.0585268326f,
0.0624188100f, 0.0663088949f, 0.0701969711f, 0.0740829225f,
0.0779666338f, 0.0818479898f, 0.0857268758f, 0.0896031775f,
0.0934767812f, 0.0973475735f, 0.1012154420f, 0.1050802730f,
0.1089419570f, 0.1128003810f, 0.1166554350f, 0.1205070100f,
0.1243549950f, 0.1281992810f, 0.1320397620f, 0.1358763280f,
0.1397088740f, 0.1435372940f, 0.1473614810f, 0.1511813320f,
0.1549967420f, 0.1588076080f, 0.1626138290f, 0.1664153010f,
0.1702119250f, 0.1740036010f, 0.1777902290f, 0.1815717110f,
0.1853479500f, 0.1891188490f, 0.1928843120f, 0.1966442450f,
0.2003985540f, 0.2041471450f, 0.2078899270f, 0.2116268090f,
0.2153577000f, 0.2190825110f, 0.2228011540f, 0.2265135410f,
0.2302195870f, 0.2339192060f, 0.2376123140f, 0.2412988270f,
0.2449786630f, 0.2486517410f, 0.2523179810f, 0.2559773030f,
0.2596296290f, 0.2632748830f, 0.2669129880f, 0.2705438680f,
0.2741674510f, 0.2777836630f, 0.2813924330f, 0.2849936890f,
0.2885873620f, 0.2921733830f, 0.2957516860f, 0.2993222020f,
0.3028848680f, 0.3064396190f, 0.3099863910f, 0.3135251230f,
0.3170557530f, 0.3205782220f, 0.3240924700f, 0.3275984410f,
0.3310960770f, 0.3345853220f, 0.3380661230f, 0.3415384250f,
0.3450021770f, 0.3484573270f, 0.3519038250f, 0.3553416220f,
0.3587706700f, 0.3621909220f, 0.3656023320f, 0.3690048540f,
0.3723984470f, 0.3757830650f, 0.3791586690f, 0.3825252170f,
0.3858826690f, 0.3892309880f, 0.3925701350f, 0.3959000740f,
0.3992207700f, 0.4025321870f, 0.4058342930f, 0.4091270550f,
0.4124104420f, 0.4156844220f, 0.4189489670f, 0.4222040480f,
0.4254496370f, 0.4286857080f, 0.4319122350f, 0.4351291940f,
0.4383365600f, 0.4415343100f, 0.4447224240f, 0.4479008790f,
0.4510696560f, 0.4542287350f, 0.4573780990f, 0.4605177290f,
0.4636476090f, 0.4667677240f, 0.4698780580f, 0.4729785980f,
0.4760693300f, 0.4791502430f, 0.4822213240f, 0.4852825630f,
0.4883339510f, 0.4913754780f, 0.4944071350f, 0.4974289160f,
0.5004408130f, 0.5034428210f, 0.5064349340f, 0.5094171490f,
0.5123894600f, 0.5153518660f, 0.5183043630f, 0.5212469510f,
0.5241796290f, 0.5271023950f, 0.5300152510f, 0.5329181980f,
0.5358112380f, 0.5386943730f, 0.5415676050f, 0.5444309400f,
0.5472843810f, 0.5501279330f, 0.5529616020f, 0.5557853940f,
0.5585993150f, 0.5614033740f, 0.5641975770f, 0.5669819340f,
0.5697564530f, 0.5725211450f, 0.5752760180f, 0.5780210840f,
0.5807563530f, 0.5834818390f, 0.5861975510f, 0.5889035040f,
0.5915997100f, 0.5942861830f, 0.5969629370f, 0.5996299860f,
0.6022873460f, 0.6049350310f, 0.6075730580f, 0.6102014430f,
0.6128202020f, 0.6154293530f, 0.6180289120f, 0.6206188990f,
0.6231993300f, 0.6257702250f, 0.6283316020f, 0.6308834820f,
0.6334258830f, 0.6359588250f, 0.6384823300f, 0.6409964180f,
0.6435011090f, 0.6459964250f, 0.6484823880f, 0.6509590190f,
0.6534263410f, 0.6558843770f, 0.6583331480f, 0.6607726790f,
0.6632029930f, 0.6656241120f, 0.6680360620f, 0.6704388650f,
0.6728325470f, 0.6752171330f, 0.6775926450f, 0.6799591110f,
0.6823165550f, 0.6846650020f, 0.6870044780f, 0.6893350100f,
0.6916566220f, 0.6939693410f, 0.6962731940f, 0.6985682070f,
0.7008544080f, 0.7031318220f, 0.7054004770f, 0.7076604000f,
0.7099116190f, 0.7121541600f, 0.7143880520f, 0.7166133230f,
0.7188300000f, 0.7210381110f, 0.7232376840f, 0.7254287490f,
0.7276113330f, 0.7297854640f, 0.7319511710f, 0.7341084830f,
0.7362574290f, 0.7383980370f, 0.7405303370f, 0.7426543560f,
0.7447701260f, 0.7468776740f, 0.7489770290f, 0.7510682220f,
0.7531512810f, 0.7552262360f, 0.7572931160f, 0.7593519510f,
0.7614027700f, 0.7634456020f, 0.7654804790f, 0.7675074280f,
0.7695264800f, 0.7715376650f, 0.7735410110f, 0.7755365500f,
0.7775243100f, 0.7795043220f, 0.7814766150f, 0.7834412190f,
0.7853981630f, 0.7853981630f /* Extended by 1 for interpolation */
};
static inline float my_sinf(float x)
{
float x2, xn;
int i;
/* Map x into the -PI to PI range. We could do this using:
* x = fmodf(x, 2.0f * FZ_PI);
* but that's C99, and seems to misbehave with negative numbers
* on some platforms. */
x -= FZ_PI;
i = x / (2.0f * FZ_PI);
x -= i * 2.0f * FZ_PI;
if (x < 0.0f)
x += 2.0f * FZ_PI;
x -= FZ_PI;
if (x <= -FZ_PI / 2.0f)
x = -FZ_PI - x;
else if (x >= FZ_PI / 2.0f)
x = FZ_PI-x;
x2 = x * x;
xn = x * x2 / 6.0f;
x -= xn;
xn *= x2 / 20.0f;
x += xn;
xn *= x2 / 42.0f;
x -= xn;
xn *= x2 / 72.0f;
x += xn;
return x;
}
static inline float my_atan2f(float o, float a)
{
int negate = 0, flip = 0, i;
float r, s;
if (o == 0.0f)
{
if (a > 0)
return 0.0f;
else
return FZ_PI;
}
if (o < 0)
o = -o, negate = 1;
if (a < 0)
a = -a, flip = 1;
if (o < a)
i = 65536.0f * o / a + 0.5f;
else
i = 65536.0f * a / o + 0.5f;
r = my_atan_table[i >> 8];
s = my_atan_table[(i >> 8) + 1];
r += (s - r) * (i & 255) / 256.0f;
if (o >= a)
r = FZ_PI / 2.0f - r;
if (flip)
r = FZ_PI - r;
if (negate)
r = -r;
return r;
}
#define sinf(x) my_sinf(x)
#define cosf(x) my_sinf(FZ_PI / 2.0f + (x))
#define atan2f(x,y) my_atan2f((x),(y))
#endif
#endif

@ -0,0 +1,189 @@
#ifndef MUPDF_FITZ_TEXT_H
#define MUPDF_FITZ_TEXT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/font.h"
#include "mupdf/fitz/path.h"
#include "mupdf/fitz/bidi.h"
/*
Text buffer.
The trm field contains the a, b, c and d coefficients.
The e and f coefficients come from the individual elements,
together they form the transform matrix for the glyph.
Glyphs are referenced by glyph ID.
The Unicode text equivalent is kept in a separate array
with indexes into the glyph array.
*/
typedef struct fz_text_s fz_text;
typedef struct fz_text_span_s fz_text_span;
typedef struct fz_text_item_s fz_text_item;
struct fz_text_item_s
{
float x, y;
int gid; /* -1 for one gid to many ucs mappings */
int ucs; /* -1 for one ucs to many gid mappings */
};
#define FZ_LANG_TAG2(c1,c2) ((c1-'a'+1) + ((c2-'a'+1)*27))
#define FZ_LANG_TAG3(c1,c2,c3) ((c1-'a'+1) + ((c2-'a'+1)*27) + ((c3-'a'+1)*27*27))
typedef enum fz_text_language_e
{
FZ_LANG_UNSET = 0,
FZ_LANG_ur = FZ_LANG_TAG2('u','r'),
FZ_LANG_urd = FZ_LANG_TAG3('u','r','d'),
FZ_LANG_ko = FZ_LANG_TAG2('k','o'),
FZ_LANG_ja = FZ_LANG_TAG2('j','a'),
FZ_LANG_zh = FZ_LANG_TAG2('z','h'),
FZ_LANG_zh_Hans = FZ_LANG_TAG3('z','h','s'),
FZ_LANG_zh_Hant = FZ_LANG_TAG3('z','h','t'),
} fz_text_language;
struct fz_text_span_s
{
fz_font *font;
fz_matrix trm;
unsigned wmode : 1; /* 0 horizontal, 1 vertical */
unsigned bidi_level : 7; /* The bidirectional level of text */
unsigned markup_dir : 2; /* The direction of text as marked in the original document */
unsigned language : 15; /* The language as marked in the original document */
int len, cap;
fz_text_item *items;
fz_text_span *next;
};
struct fz_text_s
{
int refs;
fz_text_span *head, *tail;
};
/*
fz_new_text: Create a new empty fz_text object.
Throws exception on failure to allocate.
*/
fz_text *fz_new_text(fz_context *ctx);
/*
fz_keep_text: Add a reference to a fz_text.
text: text object to keep a reference to.
Return the same text pointer.
*/
fz_text *fz_keep_text(fz_context *ctx, const fz_text *text);
/*
fz_drop_text: Drop a reference to the object, freeing
if it is the last one.
text: Object to drop the reference to.
*/
void fz_drop_text(fz_context *ctx, const fz_text *text);
/*
fz_show_glyph: Add a glyph/unicode value to a text object.
text: Text object to add to.
font: The font the glyph should be added in.
trm: The transform to use for the glyph.
glyph: The glyph id to add.
unicode: The unicode character for the glyph.
wmode: 1 for vertical mode, 0 for horizontal.
bidi_level: The bidirectional level for this glyph.
markup_dir: The direction of the text as specified in the
markup.
language: The language in use (if known, 0 otherwise)
(e.g. FZ_LANG_zh_Hans).
Throws exception on failure to allocate.
*/
void fz_show_glyph(fz_context *ctx, fz_text *text, fz_font *font, const fz_matrix *trm, int glyph, int unicode, int wmode, int bidi_level, fz_bidi_direction markup_dir, fz_text_language language);
/*
fz_show_string: Add a UTF8 string to a text object.
text: Text object to add to.
font: The font the string should be added in.
trm: The transform to use. Will be updated according
to the advance of the string on exit.
s: The utf-8 string to add.
wmode: 1 for vertical mode, 0 for horizontal.
bidi_level: The bidirectional level for this glyph.
markup_dir: The direction of the text as specified in the
markup.
language: The language in use (if known, 0 otherwise)
(e.g. FZ_LANG_zh_Hans).
Throws exception on failure to allocate.
*/
void fz_show_string(fz_context *ctx, fz_text *text, fz_font *font, fz_matrix *trm, const char *s, int wmode, int bidi_level, fz_bidi_direction markup_dir, fz_text_language language);
/*
fz_bound_text: Find the bounds of a given text object.
text: The text object to find the bounds of.
stroke: Pointer to the stroke attributes (for stroked
text), or NULL (for filled text).
ctm: The matrix in use.
r: pointer to storage for the bounds.
Returns a pointer to r, which is updated to contain the
bounding box for the text object.
*/
fz_rect *fz_bound_text(fz_context *ctx, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *r);
/*
fz_clone_text: Clone a text object.
text: The text object to clone.
Throws an exception on allocation failure.
*/
fz_text *fz_clone_text(fz_context *ctx, const fz_text *text);
/*
Convert ISO 639 (639-{1,2,3,5}) language specification
strings losslessly to a 15 bit fz_text_language code.
No validation is carried out. Obviously invalid (out
of spec) codes will be mapped to FZ_LANG_UNSET, but
well-formed (but undefined) codes will be blithely
accepted.
*/
fz_text_language fz_text_language_from_string(const char *str);
/*
Recover ISO 639 (639-{1,2,3,5}) language specification
strings losslessly from a 15 bit fz_text_language code.
No validation is carried out. See note above.
*/
char *fz_string_from_text_language(char str[8], fz_text_language lang);
#endif

@ -0,0 +1,35 @@
#ifndef TRACK_USAGE_H
#define TRACK_USAGE_H
#ifdef TRACK_USAGE
typedef struct track_usage_data_s {
int count;
const char *function;
int line;
const char *desc;
struct track_usage_data_s *next;
} track_usage_data_t;
#define TRACK_LABEL(A) \
do { \
static track_usage_data_t USAGE_DATA = { 0 };\
track_usage(&USAGE_DATA, __FILE__, __LINE__, A);\
} while (0)
#define TRACK_FN() \
do { \
static track_usage_data_t USAGE_DATA = { 0 };\
track_usage(&USAGE_DATA, __FILE__, __LINE__, __FUNCTION__);\
} while (0)
void track_usage(track_usage_data_t *data, const char *function, int line, const char *desc);
#else
#define TRACK_LABEL(A) do { } while (0)
#define TRACK_FN() do { } while (0)
#endif
#endif

@ -0,0 +1,54 @@
#ifndef MUPDF_FITZ_TRANSITION_H
#define MUPDF_FITZ_TRANSITION_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/pixmap.h"
/* Transition support */
typedef struct fz_transition_s fz_transition;
enum {
FZ_TRANSITION_NONE = 0, /* aka 'R' or 'REPLACE' */
FZ_TRANSITION_SPLIT,
FZ_TRANSITION_BLINDS,
FZ_TRANSITION_BOX,
FZ_TRANSITION_WIPE,
FZ_TRANSITION_DISSOLVE,
FZ_TRANSITION_GLITTER,
FZ_TRANSITION_FLY,
FZ_TRANSITION_PUSH,
FZ_TRANSITION_COVER,
FZ_TRANSITION_UNCOVER,
FZ_TRANSITION_FADE
};
struct fz_transition_s
{
int type;
float duration; /* Effect duration (seconds) */
/* Parameters controlling the effect */
int vertical; /* 0 or 1 */
int outwards; /* 0 or 1 */
int direction; /* Degrees */
/* Potentially more to come */
/* State variables for use of the transition code */
int state0;
int state1;
};
/*
fz_generate_transition: Generate a frame of a transition.
tpix: Target pixmap
opix: Old pixmap
npix: New pixmap
time: Position within the transition (0 to 256)
trans: Transition details
Returns 1 if successfully generated a frame.
*/
int fz_generate_transition(fz_context *ctx, fz_pixmap *tpix, fz_pixmap *opix, fz_pixmap *npix, int time, fz_transition *trans);
#endif

@ -0,0 +1,24 @@
#ifndef MUPDF_FITZ_TREE_H
#define MUPDF_FITZ_TREE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
/*
AA-tree to look up things by strings.
*/
typedef struct fz_tree_s fz_tree;
void *fz_tree_lookup(fz_context *ctx, fz_tree *node, const char *key);
/*
Insert a new key/value pair and rebalance the tree.
Return the new root of the tree after inserting and rebalancing.
May be called with a NULL root to create a new tree.
*/
fz_tree *fz_tree_insert(fz_context *ctx, fz_tree *root, const char *key, void *value);
void fz_drop_tree(fz_context *ctx, fz_tree *node, void (*dropfunc)(fz_context *ctx, void *value));
#endif

@ -0,0 +1,77 @@
#ifndef MUPDF_FITZ_UTIL_H
#define MUPDF_FITZ_UTIL_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/document.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/structured-text.h"
#include "mupdf/fitz/buffer.h"
/*
fz_new_display_list_from_page: Create a display list with the contents of a page.
*/
fz_display_list *fz_new_display_list_from_page(fz_context *ctx, fz_page *page);
fz_display_list *fz_new_display_list_from_page_number(fz_context *ctx, fz_document *doc, int number);
fz_display_list *fz_new_display_list_from_page_contents(fz_context *ctx, fz_page *page);
fz_display_list *fz_new_display_list_from_annot(fz_context *ctx, fz_annot *annot);
/*
fz_new_pixmap_from_page: Render the page to a pixmap using the transform and colorspace.
*/
fz_pixmap *fz_new_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, const fz_matrix *ctm, fz_colorspace *cs, int alpha);
fz_pixmap *fz_new_pixmap_from_page(fz_context *ctx, fz_page *page, const fz_matrix *ctm, fz_colorspace *cs, int alpha);
fz_pixmap *fz_new_pixmap_from_page_number(fz_context *ctx, fz_document *doc, int number, const fz_matrix *ctm, fz_colorspace *cs, int alpha);
/*
fz_new_pixmap_from_page_contents: Render the page contents without annotations.
*/
fz_pixmap *fz_new_pixmap_from_page_contents(fz_context *ctx, fz_page *page, const fz_matrix *ctm, fz_colorspace *cs, int alpha);
/*
fz_new_pixmap_from_annot: Render an annotation suitable for blending on top of the opaque
pixmap returned by fz_new_pixmap_from_page_contents.
*/
fz_pixmap *fz_new_pixmap_from_annot(fz_context *ctx, fz_annot *annot, const fz_matrix *ctm, fz_colorspace *cs, int alpha);
/*
fz_new_stext_page_from_page: Extract structured text from a page.
*/
fz_stext_page *fz_new_stext_page_from_page(fz_context *ctx, fz_page *page, const fz_stext_options *options);
fz_stext_page *fz_new_stext_page_from_page_number(fz_context *ctx, fz_document *doc, int number, const fz_stext_options *options);
fz_stext_page *fz_new_stext_page_from_display_list(fz_context *ctx, fz_display_list *list, const fz_stext_options *options);
/*
fz_new_buffer_from_stext_page: Convert structured text into plain text.
*/
fz_buffer *fz_new_buffer_from_stext_page(fz_context *ctx, fz_stext_page *text);
fz_buffer *fz_new_buffer_from_page(fz_context *ctx, fz_page *page, const fz_stext_options *options);
fz_buffer *fz_new_buffer_from_page_number(fz_context *ctx, fz_document *doc, int number, const fz_stext_options *options);
fz_buffer *fz_new_buffer_from_display_list(fz_context *ctx, fz_display_list *list, const fz_stext_options *options);
/*
fz_search_page: Search for the 'needle' text on the page.
Record the hits in the hit_bbox array and return the number of hits.
Will stop looking once it has filled hit_max rectangles.
*/
int fz_search_page(fz_context *ctx, fz_page *page, const char *needle, fz_rect *hit_bbox, int hit_max);
int fz_search_page_number(fz_context *ctx, fz_document *doc, int number, const char *needle, fz_rect *hit_bbox, int hit_max);
int fz_search_display_list(fz_context *ctx, fz_display_list *list, const char *needle, fz_rect *hit_bbox, int hit_max);
/*
Parse an SVG document into a display-list.
*/
fz_display_list *fz_new_display_list_from_svg(fz_context *ctx, fz_buffer *buf, float *w, float *h);
/*
Create a scalable image from an SVG document.
*/
fz_image *fz_new_image_from_svg(fz_context *ctx, fz_buffer *buf);
/*
Write image as a data URI (for HTML and SVG output).
*/
void fz_write_image_as_data_uri(fz_context *ctx, fz_output *out, fz_image *image);
#endif

@ -0,0 +1,9 @@
#ifndef MUPDF_FITZ_VERSION_H
#define MUPDF_FITZ_VERSION_H
#ifndef FZ_VERSION
#define FZ_VERSION "1.13.0"
#define FZ_VERSION_MAJOR 1
#define FZ_VERSION_MINOR 13
#define FZ_VERSION_PATCH 0
#endif
#endif

@ -0,0 +1,159 @@
#ifndef MUPDF_FITZ_WRITER_H
#define MUPDF_FITZ_WRITER_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/document.h"
#include "mupdf/fitz/device.h"
typedef struct fz_document_writer_s fz_document_writer;
/*
fz_document_writer_begin_page_fn: Function type to start
the process of writing a page to a document.
mediabox: page size rectangle in points.
Returns a fz_device to write page contents to.
*/
typedef fz_device *(fz_document_writer_begin_page_fn)(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox);
/*
fz_document_writer_end_page_fn: Function type to end the
process of writing a page to a document.
dev: The device created by the begin_page function.
*/
typedef void (fz_document_writer_end_page_fn)(fz_context *ctx, fz_document_writer *wri, fz_device *dev);
/*
fz_document_writer_close_writer_fn: Function type to end
the process of writing pages to a document.
This writes any file level trailers required. After this
completes successfully the file is up to date and complete.
*/
typedef void (fz_document_writer_close_writer_fn)(fz_context *ctx, fz_document_writer *wri);
/*
fz_document_writer_drop_writer_fn: Function type to discard
an fz_document_writer. This may be called at any time during
the process to release all the resources owned by the writer.
Calling drop without having previously called close may leave
the file in an inconsistent state and the user of the
fz_document_writer would need to do any cleanup required.
*/
typedef void (fz_document_writer_drop_writer_fn)(fz_context *ctx, fz_document_writer *wri);
/*
Structure is public to allow other structures to
be derived from it. Do not access members directly.
*/
struct fz_document_writer_s
{
fz_document_writer_begin_page_fn *begin_page;
fz_document_writer_end_page_fn *end_page;
fz_document_writer_close_writer_fn *close_writer;
fz_document_writer_drop_writer_fn *drop_writer;
fz_device *dev;
};
/*
fz_new_document_writer_of_size: Internal function to allocate a
block for a derived document_writer structure, with the base
structure's function pointers populated correctly, and the extra
space zero initialised.
*/
fz_document_writer *fz_new_document_writer_of_size(fz_context *ctx, size_t size,
fz_document_writer_begin_page_fn *begin_page,
fz_document_writer_end_page_fn *end_page,
fz_document_writer_close_writer_fn *close,
fz_document_writer_drop_writer_fn *drop);
#define fz_new_derived_document_writer(CTX,TYPE,BEGIN_PAGE,END_PAGE,CLOSE,DROP) \
((TYPE *)Memento_label(fz_new_document_writer_of_size(CTX,sizeof(TYPE),BEGIN_PAGE,END_PAGE,CLOSE,DROP),#TYPE))
int fz_has_option(fz_context *ctx, const char *opts, const char *key, const char **val);
int fz_option_eq(const char *a, const char *b);
/*
fz_new_document_writer: Create a new fz_document_writer, for a
file of the given type.
path: The document name to write (or NULL for default)
format: Which format to write (currently cbz, html, pdf, pam, pbm,
pgm, pkm, png, ppm, pnm, svg, text, tga, xhtml)
options: NULL, or pointer to comma separated string to control
file generation.
*/
fz_document_writer *fz_new_document_writer(fz_context *ctx, const char *path, const char *format, const char *options);
fz_document_writer *fz_new_pdf_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_svg_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_text_writer(fz_context *ctx, const char *format, const char *path, const char *options);
fz_document_writer *fz_new_ps_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pcl_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pwg_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_png_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_tga_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pam_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pnm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pgm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_ppm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pbm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pkm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
/*
fz_begin_page: Called to start the process of writing a page to
a document.
mediabox: page size rectangle in points.
Returns a fz_device to write page contents to.
*/
fz_device *fz_begin_page(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox);
/*
fz_end_page: Called to end the process of writing a page to a
document.
*/
void fz_end_page(fz_context *ctx, fz_document_writer *wri);
/*
fz_close_document_writer: Called to end the process of writing
pages to a document.
This writes any file level trailers required. After this
completes successfully the file is up to date and complete.
*/
void fz_close_document_writer(fz_context *ctx, fz_document_writer *wri);
/*
fz_drop_document_writer: Called to discard a fz_document_writer.
This may be called at any time during the process to release all
the resources owned by the writer.
Calling drop without having previously called close may leave
the file in an inconsistent state.
*/
void fz_drop_document_writer(fz_context *ctx, fz_document_writer *wri);
fz_document_writer *fz_new_pixmap_writer(fz_context *ctx, const char *path, const char *options, const char *default_path, int n,
void (*save)(fz_context *ctx, fz_pixmap *pix, const char *filename));
extern const char *fz_pdf_write_options_usage;
extern const char *fz_svg_write_options_usage;
extern const char *fz_pcl_write_options_usage;
extern const char *fz_pclm_write_options_usage;
extern const char *fz_pwg_write_options_usage;
#endif

@ -0,0 +1,88 @@
#ifndef MUPDF_FITZ_XML_H
#define MUPDF_FITZ_XML_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
/*
XML document model
*/
typedef struct fz_xml_doc_s fz_xml_doc;
typedef struct fz_xml_s fz_xml;
/*
fz_parse_xml: Parse the contents of buffer into a tree of xml nodes.
preserve_white: whether to keep or delete all-whitespace nodes.
*/
fz_xml_doc *fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white);
/*
fz_drop_xml: Free the XML node and all its children and siblings.
*/
void fz_drop_xml(fz_context *ctx, fz_xml_doc *xml);
/*
fz_detach_xml: Detach a node from the tree, unlinking it from its parent,
and setting the document root to the node.
*/
void fz_detach_xml(fz_context *ctx, fz_xml_doc *xml, fz_xml *node);
/*
fz_xml_root: Get the root node for the document.
*/
fz_xml *fz_xml_root(fz_xml_doc *xml);
/*
fz_xml_prev: Return previous sibling of XML node.
*/
fz_xml *fz_xml_prev(fz_xml *item);
/*
fz_xml_next: Return next sibling of XML node.
*/
fz_xml *fz_xml_next(fz_xml *item);
/*
fz_xml_up: Return parent of XML node.
*/
fz_xml *fz_xml_up(fz_xml *item);
/*
fz_xml_down: Return first child of XML node.
*/
fz_xml *fz_xml_down(fz_xml *item);
/*
fz_xml_is_tag: Return true if the tag name matches.
*/
int fz_xml_is_tag(fz_xml *item, const char *name);
/*
fz_xml_tag: Return tag of XML node. Return NULL for text nodes.
*/
char *fz_xml_tag(fz_xml *item);
/*
fz_xml_att: Return the value of an attribute of an XML node.
NULL if the attribute doesn't exist.
*/
char *fz_xml_att(fz_xml *item, const char *att);
/*
fz_xml_text: Return the text content of an XML node.
Return NULL if the node is a tag.
*/
char *fz_xml_text(fz_xml *item);
/*
fz_debug_xml: Pretty-print an XML tree to stdout.
*/
void fz_debug_xml(fz_xml *item, int level);
fz_xml *fz_xml_find(fz_xml *item, const char *tag);
fz_xml *fz_xml_find_next(fz_xml *item, const char *tag);
fz_xml *fz_xml_find_down(fz_xml *item, const char *tag);
#endif

@ -0,0 +1,299 @@
/* Copyright (C) 2009-2017 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
implied.
This software is distributed under license and may not be copied, modified
or distributed except as expressly authorized under the terms of that
license. Refer to licensing information at http://www.artifex.com
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
*/
/* Memento: A library to aid debugging of memory leaks/heap corruption.
*
* Usage (with C):
* First, build your project with MEMENTO defined, and include this
* header file wherever you use malloc, realloc or free.
* This header file will use macros to point malloc, realloc and free to
* point to Memento_malloc, Memento_realloc, Memento_free.
*
* Run your program, and all mallocs/frees/reallocs should be redirected
* through here. When the program exits, you will get a list of all the
* leaked blocks, together with some helpful statistics. You can get the
* same list of allocated blocks at any point during program execution by
* calling Memento_listBlocks();
*
* Every call to malloc/free/realloc counts as an 'allocation event'.
* On each event Memento increments a counter. Every block is tagged with
* the current counter on allocation. Every so often during program
* execution, the heap is checked for consistency. By default this happens
* after 1024 events, then after 2048 events, then after 4096 events, etc.
* This can be changed at runtime by using Memento_setParanoia(int level).
* 0 turns off such checking, 1 sets checking to happen on every event,
* any positive number n sets checking to happen once every n events,
* and any negative number n sets checking to happen after -n events, then
* after -2n events etc.
*
* The default paranoia level is therefore -1024.
*
* Memento keeps blocks around for a while after they have been freed, and
* checks them as part of these heap checks to see if they have been
* written to (or are freed twice etc).
*
* A given heap block can be checked for consistency (it's 'pre' and
* 'post' guard blocks are checked to see if they have been written to)
* by calling Memento_checkBlock(void *blockAddress);
*
* A check of all the memory can be triggered by calling Memento_check();
* (or Memento_checkAllMemory(); if you'd like it to be quieter).
*
* A good place to breakpoint is Memento_breakpoint, as this will then
* trigger your debugger if an error is detected. This is done
* automatically for debug windows builds.
*
* If a block is found to be corrupt, information will be printed to the
* console, including the address of the block, the size of the block,
* the type of corruption, the number of the block and the event on which
* it last passed a check for correctness.
*
* If you rerun, and call Memento_paranoidAt(int event); with this number
* the code will wait until it reaches that event and then start
* checking the heap after every allocation event. Assuming it is a
* deterministic failure, you should then find out where in your program
* the error is occurring (between event x-1 and event x).
*
* Then you can rerun the program again, and call
* Memento_breakAt(int event); and the program will call
* Memento_Breakpoint() when event x is reached, enabling you to step
* through.
*
* Memento_find(address) will tell you what block (if any) the given
* address is in.
*
* An example:
* Suppose we have a gs invocation that crashes with memory corruption.
* * Build with -DMEMENTO.
* * In your debugger put breakpoints on Memento_inited and
* Memento_Breakpoint.
* * Run the program. It will stop in Memento_inited.
* * Execute Memento_setParanoia(1); (In VS use Ctrl-Alt-Q). (Note #1)
* * Continue execution.
* * It will detect the memory corruption on the next allocation event
* after it happens, and stop in Memento_breakpoint. The console should
* show something like:
*
* Freed blocks:
* 0x172e610(size=288,num=1415) index 256 (0x172e710) onwards corrupted
* Block last checked OK at allocation 1457. Now 1458.
*
* * This means that the block became corrupted between allocation 1457
* and 1458 - so if we rerun and stop the program at 1457, we can then
* step through, possibly with a data breakpoint at 0x172e710 and see
* when it occurs.
* * So restart the program from the beginning. When we hit Memento_inited
* execute Memento_breakAt(1457); (and maybe Memento_setParanoia(1), or
* Memento_setParanoidAt(1457))
* * Continue execution until we hit Memento_breakpoint.
* * Now you can step through and watch the memory corruption happen.
*
* Note #1: Using Memento_setParanoia(1) can cause your program to run
* very slowly. You may instead choose to use Memento_setParanoia(100)
* (or some other figure). This will only exhaustively check memory on
* every 100th allocation event. This trades speed for the size of the
* average allocation event range in which detection of memory corruption
* occurs. You may (for example) choose to run once checking every 100
* allocations and discover that the corruption happens between events
* X and X+100. You can then rerun using Memento_paranoidAt(X), and
* it'll only start exhaustively checking when it reaches X.
*
* More than one memory allocator?
*
* If you have more than one memory allocator in the system (like for
* instance the ghostscript chunk allocator, that builds on top of the
* standard malloc and returns chunks itself), then there are some things
* to note:
*
* * If the secondary allocator gets its underlying blocks from calling
* malloc, then those will be checked by Memento, but 'subblocks' that
* are returned to the secondary allocator will not. There is currently
* no way to fix this other than trying to bypass the secondary
* allocator. One way I have found to do this with the chunk allocator
* is to tweak its idea of a 'large block' so that it puts every
* allocation in its own chunk. Clearly this negates the point of having
* a secondary allocator, and is therefore not recommended for general
* use.
*
* * Again, if the secondary allocator gets its underlying blocks from
* calling malloc (and hence Memento) leak detection should still work
* (but whole blocks will be detected rather than subblocks).
*
* * If on every allocation attempt the secondary allocator calls into
* Memento_failThisEvent(), and fails the allocation if it returns true
* then more useful features can be used; firstly memory squeezing will
* work, and secondly, Memento will have a "finer grained" paranoia
* available to it.
*
* Usage with C++:
*
* Memento has some experimental code in it to trap new/delete (and
* new[]/delete[] if required) calls.
*
* In order for this to work, either:
*
* 1) Build memento.c with the c++ compiler.
*
* or
*
* 2) Build memento.c as normal with the C compiler, then from any
* one of your .cpp files, do:
*
* #define MEMENTO_CPP_EXTRAS_ONLY
* #include "memento.c"
*
* In the case where MEMENTO is not defined, this will not do anything.
*
* Both Windows and GCC provide separate new[] and delete[] operators
* for arrays. Apparently some systems do not. If this is the case for
* your system, define MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS.
*/
#ifndef MEMENTO_H
#define MEMENTO_H
#include <stddef.h> /* for size_t */
#ifndef MEMENTO_UNDERLYING_MALLOC
#define MEMENTO_UNDERLYING_MALLOC malloc
#endif
#ifndef MEMENTO_UNDERLYING_FREE
#define MEMENTO_UNDERLYING_FREE free
#endif
#ifndef MEMENTO_UNDERLYING_REALLOC
#define MEMENTO_UNDERLYING_REALLOC realloc
#endif
#ifndef MEMENTO_UNDERLYING_CALLOC
#define MEMENTO_UNDERLYING_CALLOC calloc
#endif
#ifndef MEMENTO_MAXALIGN
#define MEMENTO_MAXALIGN (sizeof(int))
#endif
#define MEMENTO_PREFILL 0xa6
#define MEMENTO_POSTFILL 0xa7
#define MEMENTO_ALLOCFILL 0xa8
#define MEMENTO_FREEFILL 0xa9
#define MEMENTO_FREELIST_MAX 0x2000000
int Memento_checkBlock(void *);
int Memento_checkAllMemory(void);
int Memento_check(void);
int Memento_setParanoia(int);
int Memento_paranoidAt(int);
int Memento_breakAt(int);
void Memento_breakOnFree(void *a);
void Memento_breakOnRealloc(void *a);
int Memento_getBlockNum(void *);
int Memento_find(void *a);
void Memento_breakpoint(void);
int Memento_failAt(int);
int Memento_failThisEvent(void);
void Memento_listBlocks(void);
void Memento_listNewBlocks(void);
size_t Memento_setMax(size_t);
void Memento_stats(void);
void *Memento_label(void *, const char *);
void Memento_tick(void);
void *Memento_malloc(size_t s);
void *Memento_realloc(void *, size_t s);
void Memento_free(void *);
void *Memento_calloc(size_t, size_t);
void Memento_info(void *addr);
void Memento_listBlockInfo(void);
void *Memento_takeByteRef(void *blk);
void *Memento_dropByteRef(void *blk);
void *Memento_takeShortRef(void *blk);
void *Memento_dropShortRef(void *blk);
void *Memento_takeIntRef(void *blk);
void *Memento_dropIntRef(void *blk);
void *Memento_takeRef(void *blk);
void *Memento_dropRef(void *blk);
void *Memento_adjustRef(void *blk, int adjust);
void *Memento_reference(void *blk);
int Memento_checkPointerOrNull(void *blk);
int Memento_checkBytePointerOrNull(void *blk);
int Memento_checkShortPointerOrNull(void *blk);
int Memento_checkIntPointerOrNull(void *blk);
void Memento_startLeaking(void);
void Memento_stopLeaking(void);
void Memento_fin(void);
#ifdef MEMENTO
#ifndef COMPILING_MEMENTO_C
#define malloc Memento_malloc
#define free Memento_free
#define realloc Memento_realloc
#define calloc Memento_calloc
#endif
#else
#define Memento_malloc MEMENTO_UNDERLYING_MALLOC
#define Memento_free MEMENTO_UNDERLYING_FREE
#define Memento_realloc MEMENTO_UNDERLYING_REALLOC
#define Memento_calloc MEMENTO_UNDERLYING_CALLOC
#define Memento_checkBlock(A) 0
#define Memento_checkAllMemory() 0
#define Memento_check() 0
#define Memento_setParanoia(A) 0
#define Memento_paranoidAt(A) 0
#define Memento_breakAt(A) 0
#define Memento_breakOnFree(A) 0
#define Memento_breakOnRealloc(A) 0
#define Memento_getBlockNum(A) 0
#define Memento_find(A) 0
#define Memento_breakpoint() do {} while (0)
#define Memento_failAt(A) 0
#define Memento_failThisEvent() 0
#define Memento_listBlocks() do {} while (0)
#define Memento_listNewBlocks() do {} while (0)
#define Memento_setMax(A) 0
#define Memento_stats() do {} while (0)
#define Memento_label(A,B) (A)
#define Memento_info(A) do {} while (0)
#define Memento_listBlockInfo() do {} while (0)
#define Memento_takeByteRef(A) (A)
#define Memento_dropByteRef(A) (A)
#define Memento_takeShortRef(A) (A)
#define Memento_dropShortRef(A) (A)
#define Memento_takeIntRef(A) (A)
#define Memento_dropIntRef(A) (A)
#define Memento_takeRef(A) (A)
#define Memento_dropRef(A) (A)
#define Memento_adjustRef(A,V) (A)
#define Memento_reference(A) (A)
#define Memento_checkPointerOrNull(A) 0
#define Memento_checkBytePointerOrNull(A) 0
#define Memento_checkShortPointerOrNull(A) 0
#define Memento_checkIntPointerOrNull(A) 0
#define Memento_tick() do {} while (0)
#define Memento_startLeaking() do {} while (0)
#define Memento_stopLeaking() do {} while (0)
#define Memento_fin() do {} while (0)
#endif /* MEMENTO */
#endif /* MEMENTO_H */

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,27 @@
module gin-PDF-Jpegs
go 1.17
require (
github.com/gin-gonic/gin v1.7.7
github.com/karmdip-mi/go-fitz v0.0.0-20210702102225-a530a79566e9
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
)
require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)

@ -0,0 +1,60 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/karmdip-mi/go-fitz v0.0.0-20210702102225-a530a79566e9 h1:w2zV18MDGv67JnuHgNQk7CG6ipj9HEBtuZGwy6TrJEE=
github.com/karmdip-mi/go-fitz v0.0.0-20210702102225-a530a79566e9/go.mod h1:2aHtXmu2gpljEpoBoFMFr+C5GpdHIT8aI1l1UcyvEP4=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

@ -0,0 +1,186 @@
package main
import (
"bytes"
"fmt"
"image/jpeg"
"os"
"path/filepath"
"time"
"github.com/gin-gonic/gin"
// "github.com/karmdip-mi/go-fitz"
"test/go-fitz"
"github.com/ledongthuc/pdf"
"github.com/nfnt/resize"
)
func main() {
r := gin.Default()
r.GET("/parsingPdf", func(c *gin.Context) {
pdfFilePath := c.Query("pdfFilePath")
outPath := c.Query("outPath")
imgPaths, _ := parsingPDF(pdfFilePath, outPath)
c.JSON(200, gin.H{
"imgPaths": imgPaths,
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
// 解析pdf
func parsingPDF(pdfFilePath string, outPath string) ([]string, string) {
startTime := time.Now().Unix()
endTime := time.Now().Unix()
fmt.Println(startTime)
var imgPaths []string
doc, err := fitz.New(pdfFilePath)
if err != nil {
panic(err)
}
// Extract pages as images
for n := 0; n < doc.NumPage(); n++ {
// img, err := doc.Image(n)
// Image方法导出文件会比较模糊
// ImageDPI导出文件时如果dpi设置太大会导致程序直接奔溃
img, err := doc.ImageDPI(n, 200)
if err != nil {
panic(err)
}
err = os.MkdirAll(outPath, 0755)
if err != nil {
panic(err)
}
imgPath := filepath.Join(outPath, fmt.Sprintf("image-%05d.jpg", n))
imgPaths = append(imgPaths, imgPath)
f, err := os.Create(imgPath)
if err != nil {
panic(err)
}
// 修改图片的大小
m := resize.Resize(0, 2500, img, resize.Lanczos3)
// buf := bytes.Buffer{}
err = jpeg.Encode(f, m, &jpeg.Options{Quality: jpeg.DefaultQuality})
if err != nil {
panic(err)
}
f.Close()
endTime = time.Now().Unix()
fmt.Println(endTime)
fmt.Println((endTime - startTime))
}
var pdfText string
// pdfText, readErr := ReadPdf(pdfFilePath)
// if readErr!=nil{
// if err != nil {
// panic(err)
// }
// }
return imgPaths, pdfText
}
// ReadPdf 获取pdf文字内容
func ReadPdf(path string) (string, error) {
f, r, err := pdf.Open(path)
// remember close file
defer f.Close()
if err != nil {
return "", err
}
var buf bytes.Buffer
b, err := r.GetPlainText()
if err != nil {
return "", err
}
buf.ReadFrom(b)
return buf.String(), nil
}
// 阅读按行分组的文本
func ReadPdfGroup(path string) (string, error) {
f, r, err := pdf.Open(path)
defer func() {
_ = f.Close()
}()
if err != nil {
return "", err
}
totalPage := r.NumPage()
for pageIndex := 1; pageIndex <= totalPage; pageIndex++ {
p := r.Page(pageIndex)
if p.V.IsNull() {
continue
}
rows, _ := p.GetTextByRow()
for _, row := range rows {
println(">>>> row: ", row.Position)
for _, word := range row.Content {
fmt.Println(word.S)
}
}
}
return "", nil
}
// func readPdf(path string) (string, error) {
// f, r, err := pdf.Open(path)
// // remember close file
// defer f.Close()
// if err != nil {
// return "", err
// }
// var buf bytes.Buffer
// b, err := r.GetPlainText()
// if err != nil {
// return "", err
// }
// buf.ReadFrom(b)
// return buf.String(), nil
// }
// PDF格式的所有文本
// func readPdfFormatAll(path string) (string, error) {
// f, r, err := pdf.Open(path)
// // remember close file
// defer f.Close()
// if err != nil {
// return "", err
// }
// totalPage := r.NumPage()
// for pageIndex := 1; pageIndex <= totalPage; pageIndex++ {
// p := r.Page(pageIndex)
// if p.V.IsNull() {
// continue
// }
// var lastTextStyle pdf.Text
// texts := p.Content().Text
// for _, text := range texts {
// if isSameSentence(text, lastTextStyle) {
// lastTextStyle.S = lastTextStyle.S + text.S
// } else {
// fmt.Printf("Font: %s, Font-size: %f, x: %f, y: %f, content: %s \n", lastTextStyle.Font, lastTextStyle.FontSize, lastTextStyle.X, lastTextStyle.Y, lastTextStyle.S)
// lastTextStyle = text
// }
// }
// }
// return "", nil
// }

Binary file not shown.

Binary file not shown.

@ -0,0 +1,45 @@
gin-PDF-Jpegs
Gin-PDF-JPEgs 是一个基于 gin+ Go-FITz 开发的pdf转jpeg图片的项目。
## 文件结构
```shell
├─ .gitignore
│ go.mod // 项目依赖
│ go.sum
│ LICENSE
│ main.go //主程序
│ README.md
├─img //解析后的jpeg文件存放位置
│ │ readme.md
│ └─ *.jpg //生成的jpeg文件
├─pdf // 测试pdf文件存放位置
│ └─ *.pdf
└─go-fitz // go-fitz 源码存放位置(为了方便查看源码合并过来的,不需要的话可以直接删除)
```
## 安装环境
```shell
go get -u https://git.liushuai.cq.cn/lsadmin/gin-PDF-Jpegs
go mod tidy
```
## 调试
```shell
go run gin-PDF-Jpegs
```
- 浏览器访问
```
http://127.0.0.1:8080/parsingPdf?pdfFilePath=pdf/php%20convert_%E7%99%BE%E5%BA%A6%E6%90%9C%E7%B4%A2.pdf&outPath=img/
```
## 依赖
- go-fitz github.com/gen2brain/go-fitz AGPL license
- MuPDF https://mupdf.com/ AGPL license

@ -0,0 +1,45 @@
gin-PDF-Jpegs
Gin - PDF-JPEgs is a small tool for converting PDF files to Jpegs developed by gin+ Go-FITz
## directory structure
```shell
├─ .gitignore
│ go.mod // 项目依赖
│ go.sum
│ LICENSE
│ main.go //主程序
│ README.md
├─img //解析后的jpeg文件存放位置
│ │ readme.md
│ └─ *.jpg //生成的jpeg文件
├─pdf // 测试pdf文件存放位置
│ └─ *.pdf
└─go-fitz // go-fitz 源码存放位置(为了方便查看源码合并过来的,不需要的话可以直接删除)
```
## Install
```shell
go get -u https://git.liushuai.cq.cn/lsadmin/gin-PDF-Jpegs
go mod tidy
```
## debugging
```shell
go run gin-PDF-Jpegs
```
- Browser access
```
http://127.0.0.1:8080/parsingPdf?pdfFilePath=pdf/php%20convert_%E7%99%BE%E5%BA%A6%E6%90%9C%E7%B4%A2.pdf&outPath=img/
```
## Dependence
- go-fitz github.com/gen2brain/go-fitz AGPL license
- MuPDF https://mupdf.com/ AGPL license
Loading…
Cancel
Save