Add wasm tacle-bench targets
This commit is contained in:
25
targets/wasm-tacle/sequential/cjpeg_transupp/CMakeLists.txt
Normal file
25
targets/wasm-tacle/sequential/cjpeg_transupp/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
# ~~~
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
|
||||
# ~~~
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(cjpeg_transupp)
|
||||
|
||||
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
|
||||
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
|
||||
|
||||
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
|
||||
|
||||
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
|
||||
set(APP_SOURCE_FILE_PATH
|
||||
"generated/modified_sources/inline/cjpeg_transupp.c")
|
||||
else()
|
||||
set(APP_SOURCE_FILE_PATH
|
||||
"generated/modified_sources/default/cjpeg_transupp.c")
|
||||
endif()
|
||||
|
||||
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)
|
||||
|
||||
|
||||
36
targets/wasm-tacle/sequential/cjpeg_transupp/ChangeLog.txt
Executable file
36
targets/wasm-tacle/sequential/cjpeg_transupp/ChangeLog.txt
Executable file
@ -0,0 +1,36 @@
|
||||
File: cjpeg_transupp.c
|
||||
Original provenience: MediaBench II benchmark suite,
|
||||
http://euler.slu.edu/~fritts/mediabench (mirror)
|
||||
|
||||
2015-11-03:
|
||||
- Removed original header comment, replaced by TACLeBench header.
|
||||
- Removed unnecessary preprocessor macros.
|
||||
- Removed unnecessary code parts, simplified header files and include
|
||||
relationships.
|
||||
- Added prefix "cjpeg_transupp" to all global symbols.
|
||||
- Added explicit forward declarations of functions.
|
||||
- Replaced initialization code by TACLeBench-compliant initialization code.
|
||||
- Added new function cjpeg_transupp_return producing a checksum as return value.
|
||||
- Added new function cjpeg_transupp_main according to TACLeBench guidelines.
|
||||
cjpeg_transupp_main is annotated as entry-point for timing analysis.
|
||||
- Applied code formatting according to the following rules
|
||||
- Lines shall not be wider than 80 characters; whenever possible, appropriate
|
||||
line breaks shall be inserted to keep lines below 80 characters
|
||||
- Indentation is done using whitespaces only, no tabs. Code is indented by
|
||||
two whitespaces
|
||||
- Two empty lines are put between any two functions
|
||||
- In non-empty lists or index expressions, opening '(' and '[' are followed by
|
||||
one whitespace, closing ')' and ']' are preceded by one whitespace
|
||||
- In comma- or colon-separated argument lists, one whitespace is put after
|
||||
each comma/colon
|
||||
- Names of functions and global variables all start with a benchmark-specific
|
||||
prefix (here: bs_) followed by lowercase letter (e.g., bs_square)
|
||||
- For pointer types, one whitespace is put before the '*'
|
||||
- Operators within expressions shall be preceded and followed by one
|
||||
whitespace
|
||||
- Code of then- and else-parts of if-then-else statements shall be put in
|
||||
separate lines, not in the same lines as the if-condition or the keyword
|
||||
"else"
|
||||
- Opening braces '{' denoting the beginning of code for some if-else or loop
|
||||
body shall be put at the end of the same line where the keywords "if",
|
||||
"else", "for", "while" etc. occur
|
||||
417
targets/wasm-tacle/sequential/cjpeg_transupp/README
Executable file
417
targets/wasm-tacle/sequential/cjpeg_transupp/README
Executable file
@ -0,0 +1,417 @@
|
||||
The Independent JPEG Group's JPEG software
|
||||
==========================================
|
||||
|
||||
README for release 6a of 7-Feb-96
|
||||
=================================
|
||||
|
||||
This distribution contains the sixth public release of the Independent JPEG
|
||||
Group's free JPEG software. You are welcome to redistribute this software and
|
||||
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
|
||||
|
||||
Serious users of this software (particularly those incorporating it into
|
||||
larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
|
||||
our electronic mailing list. Mailing list members are notified of updates
|
||||
and have a chance to participate in technical discussions, etc.
|
||||
|
||||
This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim
|
||||
Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi,
|
||||
Ge' Weijers, and other members of the Independent JPEG Group.
|
||||
|
||||
IJG is not affiliated with the official ISO JPEG standards committee.
|
||||
|
||||
|
||||
DOCUMENTATION ROADMAP
|
||||
=====================
|
||||
|
||||
This file contains the following sections:
|
||||
|
||||
OVERVIEW General description of JPEG and the IJG software.
|
||||
LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
|
||||
REFERENCES Where to learn more about JPEG.
|
||||
ARCHIVE LOCATIONS Where to find newer versions of this software.
|
||||
RELATED SOFTWARE Other stuff you should get.
|
||||
FILE FORMAT WARS Software *not* to get.
|
||||
TO DO Plans for future IJG releases.
|
||||
|
||||
Other documentation files in the distribution are:
|
||||
|
||||
User documentation:
|
||||
install.doc How to configure and install the IJG software.
|
||||
usage.doc Usage instructions for cjpeg, djpeg, jpegtran,
|
||||
rdjpgcom, and wrjpgcom.
|
||||
*.1 Unix-style man pages for programs (same info as usage.doc).
|
||||
wizard.doc Advanced usage instructions for JPEG wizards only.
|
||||
change.log Version-to-version change highlights.
|
||||
Programmer and internal documentation:
|
||||
libjpeg.doc How to use the JPEG library in your own programs.
|
||||
example.c Sample code for calling the JPEG library.
|
||||
structure.doc Overview of the JPEG library's internal structure.
|
||||
filelist.doc Road map of IJG files.
|
||||
coderules.doc Coding style rules --- please read if you contribute code.
|
||||
|
||||
Please read at least the files install.doc and usage.doc. Useful information
|
||||
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
|
||||
ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
|
||||
|
||||
If you want to understand how the JPEG code works, we suggest reading one or
|
||||
more of the REFERENCES, then looking at the documentation files (in roughly
|
||||
the order listed) before diving into the code.
|
||||
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
|
||||
This package contains C software to implement JPEG image compression and
|
||||
decompression. JPEG (pronounced "jay-peg") is a standardized compression
|
||||
method for full-color and gray-scale images. JPEG is intended for compressing
|
||||
"real-world" scenes; line drawings, cartoons and other non-realistic images
|
||||
are not its strong suit. JPEG is lossy, meaning that the output image is not
|
||||
exactly identical to the input image. Hence you must not use JPEG if you
|
||||
have to have identical output bits. However, on typical photographic images,
|
||||
very good compression levels can be obtained with no visible change, and
|
||||
remarkably high compression levels are possible if you can tolerate a
|
||||
low-quality image. For more details, see the references, or just experiment
|
||||
with various compression settings.
|
||||
|
||||
This software implements JPEG baseline, extended-sequential, and progressive
|
||||
compression processes. Provision is made for supporting all variants of these
|
||||
processes, although some uncommon parameter settings aren't implemented yet.
|
||||
For legal reasons, we are not distributing code for the arithmetic-coding
|
||||
variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting
|
||||
the hierarchical or lossless processes defined in the standard.
|
||||
|
||||
We provide a set of library routines for reading and writing JPEG image files,
|
||||
plus two sample applications "cjpeg" and "djpeg", which use the library to
|
||||
perform conversion between JPEG and some other popular image file formats.
|
||||
The library is intended to be reused in other applications.
|
||||
|
||||
In order to support file conversion and viewing software, we have included
|
||||
considerable functionality beyond the bare JPEG coding/decoding capability;
|
||||
for example, the color quantization modules are not strictly part of JPEG
|
||||
decoding, but they are essential for output to colormapped file formats or
|
||||
colormapped displays. These extra functions can be compiled out of the
|
||||
library if not required for a particular application. We have also included
|
||||
"jpegtran", a utility for lossless transcoding between different JPEG
|
||||
processes, and "rdjpgcom" and "wrjpgcom", two simple applications for
|
||||
inserting and extracting textual comments in JFIF files.
|
||||
|
||||
The emphasis in designing this software has been on achieving portability and
|
||||
flexibility, while also making it fast enough to be useful. In particular,
|
||||
the software is not intended to be read as a tutorial on JPEG. (See the
|
||||
REFERENCES section for introductory material.) Rather, it is intended to
|
||||
be reliable, portable, industrial-strength code. We do not claim to have
|
||||
achieved that goal in every aspect of the software, but we strive for it.
|
||||
|
||||
We welcome the use of this software as a component of commercial products.
|
||||
No royalty is required, but we do ask for an acknowledgement in product
|
||||
documentation, as described under LEGAL ISSUES.
|
||||
|
||||
Lossless image transformation routines. These routines work on DCT coefficient
|
||||
arrays and thus do not require any lossy decompression or recompression of the
|
||||
image. Thanks to Guido Vollbeding for the initial design and code of this
|
||||
feature.
|
||||
|
||||
Horizontal flipping is done in-place, using a single top-to-bottom pass through
|
||||
the virtual source array. It will thus be much the fastest option for images
|
||||
larger than main memory.
|
||||
|
||||
The other routines require a set of destination virtual arrays, so they need
|
||||
twice as much memory as jpegtran normally does. The destination arrays are
|
||||
always written in normal scan order (top to bottom) because the virtual array
|
||||
manager expects this. The source arrays will be scanned in the corresponding
|
||||
order, which means multiple passes through the source arrays for most of the
|
||||
transforms. That could result in much thrashing if the image is larger than main
|
||||
memory.
|
||||
|
||||
Some notes about the operating environment of the individual transform routines:
|
||||
1. Both the source and destination virtual arrays are allocated from the source
|
||||
JPEG object, and therefore should be manipulated by calling the source's
|
||||
memory manager.
|
||||
2. The destination's component count should be used. It may be smaller than the
|
||||
source's when forcing to grayscale.
|
||||
3. Likewise the destination's sampling factors should be used. When forcing to
|
||||
grayscale the destination's sampling factors will be all 1, and we may as
|
||||
well take that as the effective iMCU size.
|
||||
4. When "trim" is in effect, the destination's dimensions will be the trimmed
|
||||
values but the source's will be untrimmed.
|
||||
5. All the routines assume that the source and destination buffers are padded
|
||||
out to a full iMCU boundary. This is true, although for the source buffer it
|
||||
is an undocumented property of jdcoefct.c.
|
||||
Notes 2,3,4 boil down to this: generally we should use the destination's
|
||||
dimensions and ignore the source's.
|
||||
|
||||
|
||||
LEGAL ISSUES
|
||||
============
|
||||
|
||||
In plain English:
|
||||
|
||||
1. We don't promise that this software works. (But if you find any bugs,
|
||||
please let us know!)
|
||||
2. You can use this software for whatever you want. You don't have to pay us.
|
||||
3. You may not pretend that you wrote this software. If you use it in a
|
||||
program, you must acknowledge somewhere in your documentation that
|
||||
you've used the IJG code.
|
||||
|
||||
In legalese:
|
||||
|
||||
The authors make NO WARRANTY or representation, either express or implied,
|
||||
with respect to this software, its quality, accuracy, merchantability, or
|
||||
fitness for a particular purpose. This software is provided "AS IS", and you,
|
||||
its user, assume the entire risk as to its quality and accuracy.
|
||||
|
||||
This software is copyright (C) 1991-1996, Thomas G. Lane.
|
||||
All Rights Reserved except as specified below.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
software (or portions thereof) for any purpose, without fee, subject to these
|
||||
conditions:
|
||||
(1) If any part of the source code for this software is distributed, then this
|
||||
README file must be included, with this copyright and no-warranty notice
|
||||
unaltered; and any additions, deletions, or changes to the original files
|
||||
must be clearly indicated in accompanying documentation.
|
||||
(2) If only executable code is distributed, then the accompanying
|
||||
documentation must state that "this software is based in part on the work of
|
||||
the Independent JPEG Group".
|
||||
(3) Permission for use of this software is granted only if the user accepts
|
||||
full responsibility for any undesirable consequences; the authors accept
|
||||
NO LIABILITY for damages of any kind.
|
||||
|
||||
These conditions apply to any software derived from or based on the IJG code,
|
||||
not just to the unmodified library. If you use our work, you ought to
|
||||
acknowledge us.
|
||||
|
||||
Permission is NOT granted for the use of any IJG author's name or company name
|
||||
in advertising or publicity relating to this software or products derived from
|
||||
it. This software may be referred to only as "the Independent JPEG Group's
|
||||
software".
|
||||
|
||||
We specifically permit and encourage the use of this software as the basis of
|
||||
commercial products, provided that all warranty or liability claims are
|
||||
assumed by the product vendor.
|
||||
|
||||
|
||||
ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
|
||||
sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
|
||||
ansi2knr.c is NOT covered by the above copyright and conditions, but instead
|
||||
by the usual distribution terms of the Free Software Foundation; principally,
|
||||
that you must include source code if you redistribute it. (See the file
|
||||
ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
|
||||
of any program generated from the IJG code, this does not limit you more than
|
||||
the foregoing paragraphs do.
|
||||
|
||||
The configuration script "configure" was produced with GNU Autoconf. It
|
||||
is copyright by the Free Software Foundation but is freely distributable.
|
||||
|
||||
It appears that the arithmetic coding option of the JPEG spec is covered by
|
||||
patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
|
||||
legally be used without obtaining one or more licenses. For this reason,
|
||||
support for arithmetic coding has been removed from the free JPEG software.
|
||||
(Since arithmetic coding provides only a marginal gain over the unpatented
|
||||
Huffman mode, it is unlikely that very many implementations will support it.)
|
||||
So far as we are aware, there are no patent restrictions on the remaining
|
||||
code.
|
||||
|
||||
WARNING: Unisys has begun to enforce their patent on LZW compression against
|
||||
GIF encoders and decoders. You will need a license from Unisys to use the
|
||||
included rdgif.c or wrgif.c files in a commercial or shareware application.
|
||||
At this time, Unisys is not enforcing their patent against freeware, so
|
||||
distribution of this package remains legal. However, we intend to remove
|
||||
GIF support from the IJG package as soon as a suitable replacement format
|
||||
becomes reasonably popular.
|
||||
|
||||
We are required to state that
|
||||
"The Graphics Interchange Format(c) is the Copyright property of
|
||||
CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
CompuServe Incorporated."
|
||||
|
||||
|
||||
REFERENCES
|
||||
==========
|
||||
|
||||
We highly recommend reading one or more of these references before trying to
|
||||
understand the innards of the JPEG software.
|
||||
|
||||
The best short technical introduction to the JPEG compression algorithm is
|
||||
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
|
||||
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
|
||||
(Adjacent articles in that issue discuss MPEG motion picture compression,
|
||||
applications of JPEG, and related topics.) If you don't have the CACM issue
|
||||
handy, a PostScript file containing a revised version of Wallace's article
|
||||
is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually
|
||||
a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
|
||||
omits the sample images that appeared in CACM, but it includes corrections
|
||||
and some added material. Note: the Wallace article is copyright ACM and
|
||||
IEEE, and it may not be used for commercial purposes.
|
||||
|
||||
A somewhat less technical, more leisurely introduction to JPEG can be found in
|
||||
"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood
|
||||
City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and
|
||||
example C code for a multitude of compression methods including JPEG. It is
|
||||
an excellent source if you are comfortable reading C code but don't know much
|
||||
about data compression in general. The book's JPEG sample code is far from
|
||||
industrial-strength, but when you are ready to look at a full implementation,
|
||||
you've got one here...
|
||||
|
||||
The best full description of JPEG is the textbook "JPEG Still Image Data
|
||||
Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
|
||||
by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp.
|
||||
The book includes the complete text of the ISO JPEG standards (DIS 10918-1
|
||||
and draft DIS 10918-2). This is by far the most complete exposition of JPEG
|
||||
in existence, and we highly recommend it.
|
||||
|
||||
The JPEG standard itself is not available electronically; you must order a
|
||||
paper copy through ISO or ITU. (Unless you feel a need to own a certified
|
||||
official copy, we recommend buying the Pennebaker and Mitchell book instead;
|
||||
it's much cheaper and includes a great deal of useful explanatory material.)
|
||||
In the USA, copies of the standard may be ordered from ANSI Sales at (212)
|
||||
642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
|
||||
doesn't take credit card orders, but Global does.) It's not cheap: as of
|
||||
1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
|
||||
shipping/handling. The standard is divided into two parts, Part 1 being the
|
||||
actual specification, while Part 2 covers compliance testing methods. Part 1
|
||||
is titled "Digital Compression and Coding of Continuous-tone Still Images,
|
||||
Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
|
||||
10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
|
||||
Continuous-tone Still Images, Part 2: Compliance testing" and has document
|
||||
numbers ISO/IEC IS 10918-2, ITU-T T.83.
|
||||
|
||||
Extensions to the original JPEG standard are defined in JPEG Part 3, a new ISO
|
||||
document. Part 3 is undergoing ISO balloting and is expected to be approved
|
||||
by the end of 1995; it will have document numbers ISO/IEC IS 10918-3, ITU-T
|
||||
T.84. IJG currently does not support any Part 3 extensions.
|
||||
|
||||
The JPEG standard does not specify all details of an interchangeable file
|
||||
format. For the omitted details we follow the "JFIF" conventions, revision
|
||||
1.02. A copy of the JFIF spec is available from:
|
||||
Literature Department
|
||||
C-Cube Microsystems, Inc.
|
||||
1778 McCarthy Blvd.
|
||||
Milpitas, CA 95035
|
||||
phone (408) 944-6300, fax (408) 944-6314
|
||||
A PostScript version of this document is available at ftp.uu.net, file
|
||||
graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube
|
||||
mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg"
|
||||
to the server to obtain the JFIF document; send the message "help" if you have
|
||||
trouble.
|
||||
|
||||
The TIFF 6.0 file format specification can be obtained by FTP from sgi.com
|
||||
(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed
|
||||
copy from Aldus Corp. at (206) 628-6593. The JPEG incorporation scheme
|
||||
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
|
||||
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
|
||||
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
|
||||
(Compression tag 7). Copies of this Note can be obtained from sgi.com or
|
||||
from ftp.uu.net:/graphics/jpeg/. It is expected that the next revision of
|
||||
the TIFF spec will replace the 6.0 JPEG design with the Note's design.
|
||||
Although IJG's own code does not support TIFF/JPEG, the free libtiff library
|
||||
uses our library to implement TIFF/JPEG per the Note. libtiff is available
|
||||
from sgi.com:/graphics/tiff/.
|
||||
|
||||
|
||||
ARCHIVE LOCATIONS
|
||||
=================
|
||||
|
||||
The "official" archive site for this software is ftp.uu.net (Internet
|
||||
address 192.48.96.9). The most recent released version can always be found
|
||||
there in directory graphics/jpeg. This particular version will be archived
|
||||
as graphics/jpeg/jpegsrc.v6a.tar.gz. If you are on the Internet, you
|
||||
can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't
|
||||
have FTP access, UUNET's archives are also available via UUCP; contact
|
||||
help@uunet.uu.net for information on retrieving files that way.
|
||||
|
||||
Numerous Internet sites maintain copies of the UUNET files. However, only
|
||||
ftp.uu.net is guaranteed to have the latest official version.
|
||||
|
||||
You can also obtain this software in DOS-compatible "zip" archive format from
|
||||
the SimTel archives (ftp.coast.net:/SimTel/msdos/graphics/), or on CompuServe
|
||||
in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 "JPEG Tools".
|
||||
Again, these versions may sometimes lag behind the ftp.uu.net release.
|
||||
|
||||
The JPEG FAQ (Frequently Asked Questions) article is a useful source of
|
||||
general information about JPEG. It is updated constantly and therefore is
|
||||
not included in this distribution. The FAQ is posted every two weeks to
|
||||
Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
|
||||
You can always obtain the latest version from the news.answers archive at
|
||||
rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and
|
||||
.../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu
|
||||
with body
|
||||
send usenet/news.answers/jpeg-faq/part1
|
||||
send usenet/news.answers/jpeg-faq/part2
|
||||
|
||||
|
||||
RELATED SOFTWARE
|
||||
================
|
||||
|
||||
Numerous viewing and image manipulation programs now support JPEG. (Quite a
|
||||
few of them use this library to do so.) The JPEG FAQ described above lists
|
||||
some of the more popular free and shareware viewers, and tells where to
|
||||
obtain them on Internet.
|
||||
|
||||
If you are on a Unix machine, we highly recommend Jef Poskanzer's free
|
||||
PBMPLUS image software, which provides many useful operations on PPM-format
|
||||
image files. In particular, it can convert PPM images to and from a wide
|
||||
range of other formats. You can obtain this package by FTP from ftp.x.org
|
||||
(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also
|
||||
a newer update of this package called NETPBM, available from
|
||||
wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/.
|
||||
Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software
|
||||
is; you are likely to have difficulty making it work on any non-Unix machine.
|
||||
|
||||
A different free JPEG implementation, written by the PVRG group at Stanford,
|
||||
is available from havefun.stanford.edu in directory pub/jpeg. This program
|
||||
is designed for research and experimentation rather than production use;
|
||||
it is slower, harder to use, and less portable than the IJG code, but it
|
||||
is easier to read and modify. Also, the PVRG code supports lossless JPEG,
|
||||
which we do not.
|
||||
|
||||
|
||||
FILE FORMAT WARS
|
||||
================
|
||||
|
||||
Some JPEG programs produce files that are not compatible with our library.
|
||||
The root of the problem is that the ISO JPEG committee failed to specify a
|
||||
concrete file format. Some vendors "filled in the blanks" on their own,
|
||||
creating proprietary formats that no one else could read. (For example, none
|
||||
of the early commercial JPEG implementations for the Macintosh were able to
|
||||
exchange compressed files.)
|
||||
|
||||
The file format we have adopted is called JFIF (see REFERENCES). This format
|
||||
has been agreed to by a number of major commercial JPEG vendors, and it has
|
||||
become the de facto standard. JFIF is a minimal or "low end" representation.
|
||||
We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
|
||||
Technical Note #2) for "high end" applications that need to record a lot of
|
||||
additional data about an image. TIFF/JPEG is fairly new and not yet widely
|
||||
supported, unfortunately.
|
||||
|
||||
The upcoming JPEG Part 3 standard defines a file format called SPIFF.
|
||||
SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
|
||||
be able to read the most common variant of SPIFF. SPIFF has some technical
|
||||
advantages over JFIF, but its major claim to fame is simply that it is an
|
||||
official standard rather than an informal one. At this point it is unclear
|
||||
whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
|
||||
standard. IJG intends to support SPIFF once the standard is frozen, but we
|
||||
have not decided whether it should become our default output format or not.
|
||||
(In any case, our decoder will remain capable of reading JFIF indefinitely.)
|
||||
|
||||
Various proprietary file formats incorporating JPEG compression also exist.
|
||||
We have little or no sympathy for the existence of these formats. Indeed,
|
||||
one of the original reasons for developing this free software was to help
|
||||
force convergence on common, open format standards for JPEG files. Don't
|
||||
use a proprietary file format!
|
||||
|
||||
|
||||
TO DO
|
||||
=====
|
||||
|
||||
In future versions, we are considering supporting some of the upcoming JPEG
|
||||
Part 3 extensions --- principally, variable quantization and the SPIFF file
|
||||
format.
|
||||
|
||||
Tuning the software for better behavior at low quality/high compression
|
||||
settings is also of interest. The current method for scaling the
|
||||
quantization tables is known not to be very good at low Q values.
|
||||
|
||||
As always, speeding things up is high on our priority list.
|
||||
|
||||
Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
|
||||
713
targets/wasm-tacle/sequential/cjpeg_transupp/cjpeg_transupp.c
Executable file
713
targets/wasm-tacle/sequential/cjpeg_transupp/cjpeg_transupp.c
Executable file
@ -0,0 +1,713 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: cjpeg_transupp
|
||||
|
||||
Author: Thomas G. Lane
|
||||
|
||||
Function: This file contains image transformation routines and other utility
|
||||
code used by the jpegtran sample application. These are NOT part of the core
|
||||
JPEG library. But we keep these routines separate from jpegtran.c to ease
|
||||
the task of maintaining jpegtran-like programs that have other user
|
||||
interfaces.
|
||||
|
||||
Source: MediaBench II
|
||||
http://euler.slu.edu/~fritts/mediabench (mirror)
|
||||
|
||||
Original name: cjpeg
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the accompanying README file.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Include section
|
||||
*/
|
||||
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
|
||||
void cjpeg_transupp_initSeed( void );
|
||||
signed char cjpeg_transupp_randomInteger( void );
|
||||
void cjpeg_transupp_init( void );
|
||||
int cjpeg_transupp_return( void );
|
||||
void cjpeg_transupp_do_flip_v( j_compress_ptr );
|
||||
void cjpeg_transupp_do_rot_90( j_compress_ptr );
|
||||
void cjpeg_transupp_do_rot_180( j_compress_ptr );
|
||||
void cjpeg_transupp_do_rot_270( j_compress_ptr );
|
||||
void cjpeg_transupp_do_transverse( j_compress_ptr );
|
||||
void cjpeg_transupp_main( void );
|
||||
int main( void );
|
||||
|
||||
|
||||
/*
|
||||
Declaration of global variables
|
||||
*/
|
||||
|
||||
volatile int cjpeg_transupp_seed;
|
||||
|
||||
signed char cjpeg_transupp_input[ 256 ];
|
||||
signed char cjpeg_transupp_input2[ 80 ];
|
||||
signed char cjpeg_transupp_input3[ 65 ];
|
||||
signed char cjpeg_transupp_input3_2[ 65 ];
|
||||
signed char cjpeg_transupp_input4[ 64 ];
|
||||
signed char cjpeg_transupp_input5[ 65 ];
|
||||
signed char cjpeg_transupp_input5_2[ 65 ];
|
||||
|
||||
/* Output arrays replace writing of results into a file. */
|
||||
signed char cjpeg_transupp_output_data[ 512 ];
|
||||
signed char cjpeg_transupp_output_data2[ 512 ];
|
||||
signed char cjpeg_transupp_output_data3[ 512 ];
|
||||
signed char cjpeg_transupp_output_data4[ 512 ];
|
||||
signed char cjpeg_transupp_output_data5[ 512 ];
|
||||
|
||||
struct jpeg_compress_struct cjpeg_transupp_dstinfo;
|
||||
|
||||
|
||||
/*
|
||||
Initialization- and return-value-related functions
|
||||
*/
|
||||
|
||||
void cjpeg_transupp_initSeed( void )
|
||||
{
|
||||
cjpeg_transupp_seed = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
cjpeg_transupp_RandomInteger generates random integers between -128 and 127.
|
||||
*/
|
||||
signed char cjpeg_transupp_randomInteger( void )
|
||||
{
|
||||
cjpeg_transupp_seed = ( ( ( cjpeg_transupp_seed * 133 ) + 81 ) % 256 ) - 128;
|
||||
return ( cjpeg_transupp_seed );
|
||||
}
|
||||
|
||||
|
||||
void cjpeg_transupp_init( void )
|
||||
{
|
||||
register int i;
|
||||
|
||||
|
||||
cjpeg_transupp_dstinfo.max_h_samp_factor = 2;
|
||||
cjpeg_transupp_dstinfo.max_v_samp_factor = 2;
|
||||
cjpeg_transupp_dstinfo.num_components = 3;
|
||||
|
||||
cjpeg_transupp_initSeed();
|
||||
|
||||
_Pragma( "loopbound min 256 max 256" )
|
||||
for ( i = 0; i < 256; i++ )
|
||||
cjpeg_transupp_input[ i ] = cjpeg_transupp_randomInteger();
|
||||
|
||||
_Pragma( "loopbound min 80 max 80" )
|
||||
for ( i = 0; i < 80; i++ )
|
||||
cjpeg_transupp_input2[ i ] = cjpeg_transupp_randomInteger();
|
||||
|
||||
_Pragma( "loopbound min 65 max 65" )
|
||||
for ( i = 0; i < 65; i++ )
|
||||
cjpeg_transupp_input3[ i ] = cjpeg_transupp_randomInteger();
|
||||
|
||||
_Pragma( "loopbound min 65 max 65" )
|
||||
for ( i = 0; i < 65; i++ )
|
||||
cjpeg_transupp_input3_2[ i ] = cjpeg_transupp_randomInteger();
|
||||
|
||||
_Pragma( "loopbound min 64 max 64" )
|
||||
for ( i = 0; i < 64; i++ )
|
||||
cjpeg_transupp_input4[ i ] = cjpeg_transupp_randomInteger();
|
||||
|
||||
_Pragma( "loopbound min 65 max 65" )
|
||||
for ( i = 0; i < 65; i++ )
|
||||
cjpeg_transupp_input5[ i ] = cjpeg_transupp_randomInteger();
|
||||
|
||||
_Pragma( "loopbound min 65 max 65" )
|
||||
for ( i = 0; i < 65; i++ )
|
||||
cjpeg_transupp_input5_2[ i ] = cjpeg_transupp_randomInteger();
|
||||
}
|
||||
|
||||
|
||||
int cjpeg_transupp_return( void )
|
||||
{
|
||||
int checksum = 0;
|
||||
unsigned int i;
|
||||
|
||||
|
||||
_Pragma( "loopbound min 512 max 512" )
|
||||
for ( i = 0; i < 512; i++ )
|
||||
checksum += cjpeg_transupp_output_data[ i ];
|
||||
|
||||
_Pragma( "loopbound min 512 max 512" )
|
||||
for ( i = 0; i < 512; i++ )
|
||||
checksum += cjpeg_transupp_output_data2[ i ];
|
||||
|
||||
_Pragma( "loopbound min 512 max 512" )
|
||||
for ( i = 0; i < 512; i++ )
|
||||
checksum += cjpeg_transupp_output_data3[ i ];
|
||||
|
||||
_Pragma( "loopbound min 512 max 512" )
|
||||
for ( i = 0; i < 512; i++ )
|
||||
checksum += cjpeg_transupp_output_data4[ i ];
|
||||
|
||||
_Pragma( "loopbound min 512 max 512" )
|
||||
for ( i = 0; i < 512; i++ )
|
||||
checksum += cjpeg_transupp_output_data5[ i ];
|
||||
|
||||
return ( checksum );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Algorithm core functions
|
||||
*/
|
||||
|
||||
/*
|
||||
Vertical flip
|
||||
*/
|
||||
void cjpeg_transupp_do_flip_v( j_compress_ptr dstinfo )
|
||||
{
|
||||
unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
|
||||
/*
|
||||
We output into a separate array because we can't touch different rows of the
|
||||
source virtual array simultaneously. Otherwise, this is a pretty
|
||||
straightforward analog of horizontal flip.
|
||||
Within a DCT block, vertical mirroring is done by changing the signs of
|
||||
odd-numbered rows.
|
||||
Partial iMCUs at the bottom edge are copied verbatim.
|
||||
*/
|
||||
MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE );
|
||||
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 19;
|
||||
unsigned int compptr_width_in_blocks = 29;
|
||||
|
||||
_Pragma( "loopbound min 3 max 3" )
|
||||
for ( ci = 0; ci < dstinfo->num_components;
|
||||
ci++, compptr_v_samp_factor = 1, compptr_width_in_blocks = 15 ) {
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
compptr_height_in_blocks = 10;
|
||||
_Pragma( "loopbound min 2 max 10" )
|
||||
for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor ) {
|
||||
|
||||
_Pragma( "loopbound min 1 max 8" )
|
||||
for ( offset_y = 0; offset_y < compptr_v_samp_factor; offset_y++ ) {
|
||||
if ( dst_blk_y < comp_height ) {
|
||||
|
||||
/* Row is within the mirrorable area. */
|
||||
_Pragma( "loopbound min 15 max 29" )
|
||||
for ( dst_blk_x = 0; dst_blk_x < compptr_width_in_blocks;
|
||||
dst_blk_x++ ) {
|
||||
|
||||
src_ptr = cjpeg_transupp_input;
|
||||
dst_ptr = cjpeg_transupp_output_data;
|
||||
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( i = 0; i < DCTSIZE; i += 2 ) {
|
||||
|
||||
/* copy even row */
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
do {
|
||||
if ( dst_blk_x < comp_height )
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
j++;
|
||||
} while ( j < DCTSIZE );
|
||||
|
||||
/* copy odd row with sign change */
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
do {
|
||||
if ( dst_blk_x < comp_height )
|
||||
*dst_ptr++ = - *src_ptr++;
|
||||
j++;
|
||||
} while ( j < DCTSIZE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
90 degree rotation is equivalent to
|
||||
1. Transposing the image;
|
||||
2. Horizontal mirroring.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
void cjpeg_transupp_do_rot_90( j_compress_ptr dstinfo )
|
||||
{
|
||||
unsigned int MCU_cols, comp_width, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
|
||||
/*
|
||||
Because of the horizontal mirror step, we can't process partial iMCUs at the
|
||||
(output) right edge properly. They just get transposed and not mirrored.
|
||||
*/
|
||||
MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE );
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
|
||||
_Pragma( "loopbound min 3 max 3" )
|
||||
for ( ci = 0; ci < dstinfo->num_components;
|
||||
ci++, compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
|
||||
_Pragma( "loopbound min 4 max 15" )
|
||||
for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor ) {
|
||||
|
||||
offset_y = 0;
|
||||
_Pragma( "loopbound min 1 max 8" )
|
||||
for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) {
|
||||
dst_blk_x = 0;
|
||||
_Pragma( "loopbound min 10 max 10" )
|
||||
for ( ; dst_blk_x < compptr_width_in_blocks;
|
||||
dst_blk_x += compptr_h_samp_factor ) {
|
||||
|
||||
offset_x = 0;
|
||||
_Pragma( "loopbound min 1 max 2" )
|
||||
for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) {
|
||||
|
||||
src_ptr = cjpeg_transupp_input2;
|
||||
|
||||
if ( dst_blk_x < comp_width ) {
|
||||
|
||||
/* Block is within the mirrorable area. */
|
||||
dst_ptr = cjpeg_transupp_output_data2;
|
||||
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( i = 0; i < DCTSIZE; i++ ) {
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( ; j < DCTSIZE; j++ )
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
|
||||
i++;
|
||||
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( j = 0; j < DCTSIZE; j++ )
|
||||
dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
} else {
|
||||
/* Edge blocks are transposed but not mirrored. */
|
||||
dst_ptr = cjpeg_transupp_output_data2;
|
||||
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( i = 0; i < DCTSIZE; i++ )
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( ; j < DCTSIZE; j++ ) {
|
||||
if ( dst_blk_y < comp_width )
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
270 degree rotation is equivalent to
|
||||
1. Horizontal mirroring;
|
||||
2. Transposing the image.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
void cjpeg_transupp_do_rot_270( j_compress_ptr dstinfo )
|
||||
{
|
||||
unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
|
||||
/*
|
||||
Because of the horizontal mirror step, we can't process partial iMCUs at the
|
||||
(output) bottom edge properly. They just get transposed and not mirrored.
|
||||
*/
|
||||
MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE );
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
_Pragma( "loopbound min 3 max 3" )
|
||||
for ( ci = 0; ci < dstinfo->num_components;
|
||||
ci++, compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) {
|
||||
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma( "loopbound min 4 max 15" )
|
||||
for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor ) {
|
||||
|
||||
offset_y = 0;
|
||||
_Pragma( "loopbound min 1 max 8" )
|
||||
for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) {
|
||||
dst_blk_x = 0;
|
||||
_Pragma( "loopbound min 10 max 10" )
|
||||
for ( ; dst_blk_x < compptr_width_in_blocks;
|
||||
dst_blk_x += compptr_h_samp_factor ) {
|
||||
|
||||
offset_x = 0;
|
||||
_Pragma( "loopbound min 1 max 2" )
|
||||
for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data3;
|
||||
|
||||
if ( dst_blk_y < comp_height ) {
|
||||
|
||||
/* Block is within the mirrorable area. */
|
||||
src_ptr = cjpeg_transupp_input3;
|
||||
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( i = 0; i < DCTSIZE; i++ ) {
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( ; j < DCTSIZE; j++ ) {
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
j++;
|
||||
dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/* Edge blocks are transposed but not mirrored. */
|
||||
src_ptr = cjpeg_transupp_input3_2;
|
||||
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( i = 0; i < DCTSIZE; i++ )
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( ; j < DCTSIZE; j++ ) {
|
||||
if ( dst_blk_y < comp_height )
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
180 degree rotation is equivalent to
|
||||
1. Vertical mirroring;
|
||||
2. Horizontal mirroring.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
void cjpeg_transupp_do_rot_180( j_compress_ptr dstinfo )
|
||||
{
|
||||
unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x,
|
||||
dst_blk_y;
|
||||
int ci, i, j, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_width_in_blocks = 29;
|
||||
unsigned int compptr_height_in_blocks = 19;
|
||||
|
||||
|
||||
MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE );
|
||||
MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE );
|
||||
|
||||
_Pragma( "loopbound min 3 max 3" )
|
||||
for ( ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_width_in_blocks = 15, compptr_height_in_blocks = 10 ) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma( "loopbound min 3 max 10" )
|
||||
for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor ) {
|
||||
offset_y = 0;
|
||||
_Pragma( "loopbound min 1 max 8" )
|
||||
for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) {
|
||||
if ( dst_blk_y < comp_height ) {
|
||||
|
||||
/* Row is within the mirrorable area. */
|
||||
|
||||
/* Process the blocks that can be mirrored both ways. */
|
||||
_Pragma( "loopbound min 14 max 28" )
|
||||
for ( dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++ ) {
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( i = 0; i < DCTSIZE; i += 2 ) {
|
||||
j = 0;
|
||||
/* For even row, negate every odd column. */
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( ; j < DCTSIZE; j += 2 ) {
|
||||
if ( dst_blk_x < comp_height ) {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
*dst_ptr++ = - *src_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
/* For odd row, negate every even column. */
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( ; j < DCTSIZE; j += 2 ) {
|
||||
if ( dst_blk_x < comp_height ) {
|
||||
*dst_ptr++ = - *src_ptr++;
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Any remaining right-edge blocks are only mirrored vertically. */
|
||||
_Pragma( "loopbound min 1 max 1" )
|
||||
for ( ; dst_blk_x < compptr_width_in_blocks; dst_blk_x++ ) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( i = 0; i < DCTSIZE; i += 2 ) {
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( ; j < DCTSIZE; j++ )
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( ; j < DCTSIZE; j++ )
|
||||
*dst_ptr++ = - *src_ptr++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/* Remaining rows are just mirrored horizontally. */
|
||||
dst_blk_x = 0;
|
||||
/* Process the blocks that can be mirrored. */
|
||||
_Pragma( "loopbound min 14 max 14" )
|
||||
do {
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
|
||||
i = 0;
|
||||
_Pragma( "loopbound min 32 max 32" )
|
||||
while ( i < DCTSIZE2 ) {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
*dst_ptr++ = - *src_ptr++;
|
||||
i += 2;
|
||||
dst_ptr += 0;
|
||||
}
|
||||
dst_blk_x++;
|
||||
dst_ptr += 0;
|
||||
} while ( dst_blk_x < comp_width );
|
||||
|
||||
/* Any remaining right-edge blocks are only copied. */
|
||||
_Pragma( "loopbound min 1 max 1" )
|
||||
for ( ; dst_blk_x < compptr_width_in_blocks; dst_blk_x++ ) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
_Pragma( "loopbound min 1 max 1" )
|
||||
do {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
i++;
|
||||
} while ( i < DCTSIZE2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Transverse transpose is equivalent to
|
||||
1. 180 degree rotation;
|
||||
2. Transposition;
|
||||
or
|
||||
1. Horizontal mirroring;
|
||||
2. Transposition;
|
||||
3. Horizontal mirroring.
|
||||
These steps are merged into a single processing routine.
|
||||
*/
|
||||
void cjpeg_transupp_do_transverse( j_compress_ptr dstinfo )
|
||||
{
|
||||
unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x,
|
||||
dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
|
||||
MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE );
|
||||
MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE );
|
||||
|
||||
_Pragma( "loopbound min 3 max 3" )
|
||||
for ( ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma( "loopbound min 4 max 15" )
|
||||
for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor ) {
|
||||
offset_y = 0;
|
||||
_Pragma( "loopbound min 1 max 8" )
|
||||
do {
|
||||
dst_blk_x = 0;
|
||||
_Pragma( "loopbound min 5 max 10" )
|
||||
do {
|
||||
offset_x = 0;
|
||||
_Pragma( "loopbound min 1 max 2" )
|
||||
for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) {
|
||||
|
||||
if ( dst_blk_y < comp_height ) {
|
||||
src_ptr = cjpeg_transupp_input5;
|
||||
|
||||
if ( dst_blk_x < comp_width ) {
|
||||
/* Block is within the mirrorable area. */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( i = 0; i < DCTSIZE; i++ ) {
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( ; j < DCTSIZE; j++ ) {
|
||||
if ( dst_blk_y < comp_width )
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
j++;
|
||||
dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
i++;
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( j = 0; j < DCTSIZE; j++ ) {
|
||||
if ( dst_blk_y < comp_width )
|
||||
dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ];
|
||||
j++;
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Right-edge blocks are mirrored in y only */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( i = 0; i < DCTSIZE; i++ ) {
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( ; j < DCTSIZE; j++ ) {
|
||||
if ( dst_blk_y < comp_width )
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
j++;
|
||||
dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
src_ptr = cjpeg_transupp_input5_2;
|
||||
|
||||
if ( dst_blk_x < comp_width ) {
|
||||
/* Bottom-edge blocks are mirrored in x only */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
|
||||
_Pragma( "loopbound min 4 max 4" )
|
||||
for ( i = 0; i < DCTSIZE; i++ ) {
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( ; j < DCTSIZE; j++ )
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
i++;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( j = 0; j < DCTSIZE; j++ )
|
||||
dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
} else {
|
||||
/* At lower right corner, just transpose, no mirroring */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( i = 0; i < DCTSIZE; i++ ) {
|
||||
j = 0;
|
||||
_Pragma( "loopbound min 8 max 8" )
|
||||
for ( ; j < DCTSIZE; j++ )
|
||||
dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ];
|
||||
}
|
||||
}
|
||||
}
|
||||
dst_blk_x += compptr_h_samp_factor;
|
||||
}
|
||||
} while ( dst_blk_x < compptr_width_in_blocks );
|
||||
offset_y++;
|
||||
} while ( offset_y < compptr_v_samp_factor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Main functions
|
||||
*/
|
||||
|
||||
void _Pragma ( "entrypoint" ) cjpeg_transupp_main( void )
|
||||
{
|
||||
cjpeg_transupp_dstinfo.image_width = 227;
|
||||
cjpeg_transupp_dstinfo.image_height = 149;
|
||||
|
||||
cjpeg_transupp_do_flip_v( &cjpeg_transupp_dstinfo );
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 149;
|
||||
cjpeg_transupp_dstinfo.image_height = 227;
|
||||
|
||||
cjpeg_transupp_do_rot_90( &cjpeg_transupp_dstinfo );
|
||||
cjpeg_transupp_do_rot_270( &cjpeg_transupp_dstinfo );
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 227;
|
||||
cjpeg_transupp_dstinfo.image_height = 149;
|
||||
|
||||
cjpeg_transupp_do_rot_180( &cjpeg_transupp_dstinfo );
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 149;
|
||||
cjpeg_transupp_dstinfo.image_height = 227;
|
||||
|
||||
cjpeg_transupp_do_transverse( &cjpeg_transupp_dstinfo );
|
||||
}
|
||||
|
||||
|
||||
int main( void )
|
||||
{
|
||||
cjpeg_transupp_init();
|
||||
cjpeg_transupp_main();
|
||||
|
||||
return ( cjpeg_transupp_return() - 1624 != 0 );
|
||||
}
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,743 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: cjpeg_transupp
|
||||
|
||||
Author: Thomas G. Lane
|
||||
|
||||
Function: This file contains image transformation routines and other utility
|
||||
code used by the jpegtran sample application. These are NOT part of the core
|
||||
JPEG library. But we keep these routines separate from jpegtran.c to ease
|
||||
the task of maintaining jpegtran-like programs that have other user
|
||||
interfaces.
|
||||
|
||||
Source: MediaBench II
|
||||
http://euler.slu.edu/~fritts/mediabench (mirror)
|
||||
|
||||
Original name: cjpeg
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the accompanying README file.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Include section
|
||||
*/
|
||||
|
||||
#include "jpeglib.h"
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
void cjpeg_transupp_initSeed(void);
|
||||
signed char cjpeg_transupp_randomInteger(void);
|
||||
void cjpeg_transupp_init(void);
|
||||
int cjpeg_transupp_return(void);
|
||||
void cjpeg_transupp_do_flip_v(j_compress_ptr);
|
||||
void cjpeg_transupp_do_rot_90(j_compress_ptr);
|
||||
void cjpeg_transupp_do_rot_180(j_compress_ptr);
|
||||
void cjpeg_transupp_do_rot_270(j_compress_ptr);
|
||||
void cjpeg_transupp_do_transverse(j_compress_ptr);
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
cjpeg_transupp_main(void);
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
|
||||
|
||||
/*
|
||||
Declaration of global variables
|
||||
*/
|
||||
|
||||
volatile int cjpeg_transupp_seed;
|
||||
|
||||
signed char cjpeg_transupp_input[256];
|
||||
signed char cjpeg_transupp_input2[80];
|
||||
signed char cjpeg_transupp_input3[65];
|
||||
signed char cjpeg_transupp_input3_2[65];
|
||||
signed char cjpeg_transupp_input4[64];
|
||||
signed char cjpeg_transupp_input5[65];
|
||||
signed char cjpeg_transupp_input5_2[65];
|
||||
|
||||
/* Output arrays replace writing of results into a file. */
|
||||
signed char cjpeg_transupp_output_data[512];
|
||||
signed char cjpeg_transupp_output_data2[512];
|
||||
signed char cjpeg_transupp_output_data3[512];
|
||||
signed char cjpeg_transupp_output_data4[512];
|
||||
signed char cjpeg_transupp_output_data5[512];
|
||||
|
||||
struct jpeg_compress_struct cjpeg_transupp_dstinfo;
|
||||
|
||||
/*
|
||||
Initialization- and return-value-related functions
|
||||
*/
|
||||
|
||||
void
|
||||
cjpeg_transupp_initSeed(void) {
|
||||
cjpeg_transupp_seed = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
cjpeg_transupp_RandomInteger generates random integers between -128 and 127.
|
||||
*/
|
||||
signed char
|
||||
cjpeg_transupp_randomInteger(void) {
|
||||
cjpeg_transupp_seed = (((cjpeg_transupp_seed * 133) + 81) % 256) - 128;
|
||||
return (cjpeg_transupp_seed);
|
||||
}
|
||||
|
||||
void
|
||||
cjpeg_transupp_init(void) {
|
||||
register int i;
|
||||
|
||||
cjpeg_transupp_dstinfo.max_h_samp_factor = 2;
|
||||
cjpeg_transupp_dstinfo.max_v_samp_factor = 2;
|
||||
cjpeg_transupp_dstinfo.num_components = 3;
|
||||
|
||||
cjpeg_transupp_initSeed();
|
||||
|
||||
__pragma_loopbound(256, 256);
|
||||
for (i = 0; i < 256; i++)
|
||||
cjpeg_transupp_input[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(80, 80);
|
||||
for (i = 0; i < 80; i++)
|
||||
cjpeg_transupp_input2[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(65, 65);
|
||||
for (i = 0; i < 65; i++)
|
||||
cjpeg_transupp_input3[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(65, 65);
|
||||
for (i = 0; i < 65; i++)
|
||||
cjpeg_transupp_input3_2[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(64, 64);
|
||||
for (i = 0; i < 64; i++)
|
||||
cjpeg_transupp_input4[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(65, 65);
|
||||
for (i = 0; i < 65; i++)
|
||||
cjpeg_transupp_input5[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(65, 65);
|
||||
for (i = 0; i < 65; i++)
|
||||
cjpeg_transupp_input5_2[i] = cjpeg_transupp_randomInteger();
|
||||
}
|
||||
|
||||
int
|
||||
cjpeg_transupp_return(void) {
|
||||
int checksum = 0;
|
||||
unsigned int i;
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data[i];
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data2[i];
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data3[i];
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data4[i];
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data5[i];
|
||||
|
||||
return (checksum);
|
||||
}
|
||||
|
||||
/*
|
||||
Algorithm core functions
|
||||
*/
|
||||
|
||||
/*
|
||||
Vertical flip
|
||||
*/
|
||||
void
|
||||
cjpeg_transupp_do_flip_v(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
/*
|
||||
We output into a separate array because we can't touch different rows of
|
||||
the source virtual array simultaneously. Otherwise, this is a pretty
|
||||
straightforward analog of horizontal flip.
|
||||
Within a DCT block, vertical mirroring is done by changing the signs of
|
||||
odd-numbered rows.
|
||||
Partial iMCUs at the bottom edge are copied verbatim.
|
||||
*/
|
||||
MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
|
||||
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 19;
|
||||
unsigned int compptr_width_in_blocks = 29;
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components;
|
||||
ci++, compptr_v_samp_factor = 1, compptr_width_in_blocks = 15) {
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
compptr_height_in_blocks = 10;
|
||||
_Pragma(
|
||||
"loopbound min 2 max 10") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
|
||||
__pragma_loopbound(1, 8);
|
||||
for (offset_y = 0; offset_y < compptr_v_samp_factor; offset_y++) {
|
||||
if (dst_blk_y < comp_height) {
|
||||
|
||||
/* Row is within the mirrorable area. */
|
||||
_Pragma(
|
||||
"loopbound min 15 max 29") for (dst_blk_x = 0;
|
||||
dst_blk_x <
|
||||
compptr_width_in_blocks;
|
||||
dst_blk_x++) {
|
||||
|
||||
src_ptr = cjpeg_transupp_input;
|
||||
dst_ptr = cjpeg_transupp_output_data;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i += 2) {
|
||||
|
||||
/* copy even row */
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
do {
|
||||
if (dst_blk_x < comp_height)
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
j++;
|
||||
} while (j < DCTSIZE);
|
||||
|
||||
/* copy odd row with sign change */
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
do {
|
||||
if (dst_blk_x < comp_height)
|
||||
*dst_ptr++ = -*src_ptr++;
|
||||
j++;
|
||||
} while (j < DCTSIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
90 degree rotation is equivalent to
|
||||
1. Transposing the image;
|
||||
2. Horizontal mirroring.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
void
|
||||
cjpeg_transupp_do_rot_90(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_cols, comp_width, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
/*
|
||||
Because of the horizontal mirror step, we can't process partial iMCUs at
|
||||
the (output) right edge properly. They just get transposed and not
|
||||
mirrored.
|
||||
*/
|
||||
MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 4 max 15") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
|
||||
offset_y = 0;
|
||||
__pragma_loopbound(1, 8);
|
||||
for (; offset_y < compptr_v_samp_factor; offset_y++) {
|
||||
dst_blk_x = 0;
|
||||
__pragma_loopbound(10, 10);
|
||||
for (; dst_blk_x < compptr_width_in_blocks;
|
||||
dst_blk_x += compptr_h_samp_factor) {
|
||||
|
||||
offset_x = 0;
|
||||
__pragma_loopbound(1, 2);
|
||||
for (; offset_x < compptr_h_samp_factor; offset_x++) {
|
||||
|
||||
src_ptr = cjpeg_transupp_input2;
|
||||
|
||||
if (dst_blk_x < comp_width) {
|
||||
|
||||
/* Block is within the mirrorable area. */
|
||||
dst_ptr = cjpeg_transupp_output_data2;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (; j < DCTSIZE; j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
|
||||
i++;
|
||||
|
||||
__pragma_loopbound(8, 8);
|
||||
for (j = 0; j < DCTSIZE; j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
} else {
|
||||
/* Edge blocks are transposed but not mirrored. */
|
||||
dst_ptr = cjpeg_transupp_output_data2;
|
||||
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++)
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (; j < DCTSIZE; j++) {
|
||||
if (dst_blk_y < comp_width)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
270 degree rotation is equivalent to
|
||||
1. Horizontal mirroring;
|
||||
2. Transposing the image.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
void
|
||||
cjpeg_transupp_do_rot_270(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
/*
|
||||
Because of the horizontal mirror step, we can't process partial iMCUs at
|
||||
the (output) bottom edge properly. They just get transposed and not
|
||||
mirrored.
|
||||
*/
|
||||
MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10) {
|
||||
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 4 max 15") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
|
||||
offset_y = 0;
|
||||
__pragma_loopbound(1, 8);
|
||||
for (; offset_y < compptr_v_samp_factor; offset_y++) {
|
||||
dst_blk_x = 0;
|
||||
__pragma_loopbound(10, 10);
|
||||
for (; dst_blk_x < compptr_width_in_blocks;
|
||||
dst_blk_x += compptr_h_samp_factor) {
|
||||
|
||||
offset_x = 0;
|
||||
__pragma_loopbound(1, 2);
|
||||
for (; offset_x < compptr_h_samp_factor; offset_x++) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data3;
|
||||
|
||||
if (dst_blk_y < comp_height) {
|
||||
|
||||
/* Block is within the mirrorable area. */
|
||||
src_ptr = cjpeg_transupp_input3;
|
||||
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
__pragma_loopbound(4, 4);
|
||||
for (; j < DCTSIZE; j++) {
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
j++;
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/* Edge blocks are transposed but not mirrored. */
|
||||
src_ptr = cjpeg_transupp_input3_2;
|
||||
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++)
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (; j < DCTSIZE; j++) {
|
||||
if (dst_blk_y < comp_height)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
180 degree rotation is equivalent to
|
||||
1. Vertical mirroring;
|
||||
2. Horizontal mirroring.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
void
|
||||
cjpeg_transupp_do_rot_180(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x,
|
||||
dst_blk_y;
|
||||
int ci, i, j, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_width_in_blocks = 29;
|
||||
unsigned int compptr_height_in_blocks = 19;
|
||||
|
||||
MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
|
||||
MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_width_in_blocks = 15, compptr_height_in_blocks = 10) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 3 max 10") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
offset_y = 0;
|
||||
__pragma_loopbound(1, 8);
|
||||
for (; offset_y < compptr_v_samp_factor; offset_y++) {
|
||||
if (dst_blk_y < comp_height) {
|
||||
|
||||
/* Row is within the mirrorable area. */
|
||||
|
||||
/* Process the blocks that can be mirrored both ways. */
|
||||
__pragma_loopbound(14, 28);
|
||||
for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i += 2) {
|
||||
j = 0;
|
||||
/* For even row, negate every odd column. */
|
||||
__pragma_loopbound(4, 4);
|
||||
for (; j < DCTSIZE; j += 2) {
|
||||
if (dst_blk_x < comp_height) {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
*dst_ptr++ = -*src_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
/* For odd row, negate every even column. */
|
||||
__pragma_loopbound(4, 4);
|
||||
for (; j < DCTSIZE; j += 2) {
|
||||
if (dst_blk_x < comp_height) {
|
||||
*dst_ptr++ = -*src_ptr++;
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Any remaining right-edge blocks are only mirrored
|
||||
* vertically. */
|
||||
_Pragma(
|
||||
"loopbound min 1 max 1") for (; dst_blk_x <
|
||||
compptr_width_in_blocks;
|
||||
dst_blk_x++) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i += 2) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (; j < DCTSIZE;
|
||||
j++) *dst_ptr++ =
|
||||
*src_ptr++;
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (; j < DCTSIZE;
|
||||
j++) *dst_ptr++ =
|
||||
-*src_ptr++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/* Remaining rows are just mirrored horizontally. */
|
||||
dst_blk_x = 0;
|
||||
/* Process the blocks that can be mirrored. */
|
||||
__pragma_loopbound(14, 14);
|
||||
do {
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
|
||||
i = 0;
|
||||
__pragma_loopbound(32, 32);
|
||||
while (i < DCTSIZE2) {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
*dst_ptr++ = -*src_ptr++;
|
||||
i += 2;
|
||||
dst_ptr += 0;
|
||||
}
|
||||
dst_blk_x++;
|
||||
dst_ptr += 0;
|
||||
} while (dst_blk_x < comp_width);
|
||||
|
||||
/* Any remaining right-edge blocks are only copied. */
|
||||
_Pragma(
|
||||
"loopbound min 1 max 1") for (; dst_blk_x <
|
||||
compptr_width_in_blocks;
|
||||
dst_blk_x++) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
__pragma_loopbound(1, 1);
|
||||
do {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
i++;
|
||||
} while (i < DCTSIZE2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Transverse transpose is equivalent to
|
||||
1. 180 degree rotation;
|
||||
2. Transposition;
|
||||
or
|
||||
1. Horizontal mirroring;
|
||||
2. Transposition;
|
||||
3. Horizontal mirroring.
|
||||
These steps are merged into a single processing routine.
|
||||
*/
|
||||
void
|
||||
cjpeg_transupp_do_transverse(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x,
|
||||
dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
|
||||
MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 4 max 15") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
offset_y = 0;
|
||||
__pragma_loopbound(1, 8);
|
||||
do {
|
||||
dst_blk_x = 0;
|
||||
__pragma_loopbound(5, 10);
|
||||
do {
|
||||
offset_x = 0;
|
||||
__pragma_loopbound(1, 2);
|
||||
for (; offset_x < compptr_h_samp_factor; offset_x++) {
|
||||
|
||||
if (dst_blk_y < comp_height) {
|
||||
src_ptr = cjpeg_transupp_input5;
|
||||
|
||||
if (dst_blk_x < comp_width) {
|
||||
/* Block is within the mirrorable area. */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 4 max 4") for (; j <
|
||||
DCTSIZE;
|
||||
j++) {
|
||||
if (dst_blk_y < comp_width)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
j++;
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
i++;
|
||||
_Pragma(
|
||||
"loopbound min 4 max 4") for (j = 0;
|
||||
j <
|
||||
DCTSIZE;
|
||||
j++) {
|
||||
if (dst_blk_y < comp_width)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
j++;
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Right-edge blocks are mirrored in y only */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 4 max 4") for (; j <
|
||||
DCTSIZE;
|
||||
j++) {
|
||||
if (dst_blk_y < comp_width)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
j++;
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
src_ptr = cjpeg_transupp_input5_2;
|
||||
|
||||
if (dst_blk_x < comp_width) {
|
||||
/* Bottom-edge blocks are mirrored in x only */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (; j <
|
||||
DCTSIZE;
|
||||
j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
i++;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (j = 0;
|
||||
j <
|
||||
DCTSIZE;
|
||||
j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
} else {
|
||||
/* At lower right corner, just transpose, no
|
||||
* mirroring */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (; j <
|
||||
DCTSIZE;
|
||||
j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
dst_blk_x += compptr_h_samp_factor;
|
||||
}
|
||||
} while (dst_blk_x < compptr_width_in_blocks);
|
||||
offset_y++;
|
||||
} while (offset_y < compptr_v_samp_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Main functions
|
||||
*/
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
cjpeg_transupp_main(void) {
|
||||
cjpeg_transupp_dstinfo.image_width = 227;
|
||||
cjpeg_transupp_dstinfo.image_height = 149;
|
||||
|
||||
cjpeg_transupp_do_flip_v(&cjpeg_transupp_dstinfo);
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 149;
|
||||
cjpeg_transupp_dstinfo.image_height = 227;
|
||||
|
||||
cjpeg_transupp_do_rot_90(&cjpeg_transupp_dstinfo);
|
||||
cjpeg_transupp_do_rot_270(&cjpeg_transupp_dstinfo);
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 227;
|
||||
cjpeg_transupp_dstinfo.image_height = 149;
|
||||
|
||||
cjpeg_transupp_do_rot_180(&cjpeg_transupp_dstinfo);
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 149;
|
||||
cjpeg_transupp_dstinfo.image_height = 227;
|
||||
|
||||
cjpeg_transupp_do_transverse(&cjpeg_transupp_dstinfo);
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void) {
|
||||
cjpeg_transupp_init();
|
||||
cjpeg_transupp_main();
|
||||
|
||||
return (cjpeg_transupp_return() - 1624 != 0);
|
||||
}
|
||||
@ -0,0 +1,743 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: jpeglib
|
||||
|
||||
Author: Thomas G. Lane
|
||||
|
||||
Function: This file defines the application interface for the JPEG library.
|
||||
Most applications using the library need only include this file, and perhaps
|
||||
jerror.h if they want to know the exact error codes.
|
||||
|
||||
Source: MediaBench II
|
||||
http://euler.slu.edu/~fritts/mediabench (mirror)
|
||||
|
||||
Original name: cjpeg
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the accompanying README file.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef JPEGLIB_H
|
||||
#define JPEGLIB_H
|
||||
|
||||
/*
|
||||
Various constants determining the sizes of things.
|
||||
All of these are specified by the JPEG standard, so don't change them if you
|
||||
want to be compatible.
|
||||
*/
|
||||
|
||||
/* The basic DCT block is 8x8 samples */
|
||||
#define DCTSIZE 8
|
||||
|
||||
/* DCTSIZE squared; # of elements in a block */
|
||||
#define DCTSIZE2 64
|
||||
|
||||
/*
|
||||
Data structures for images (arrays of samples and of DCT coefficients).
|
||||
On 80x86 machines, the image arrays are too big for near pointers, but the
|
||||
pointer arrays can fit in near memory.
|
||||
*/
|
||||
|
||||
/* ptr to one image row of pixel samples. */
|
||||
typedef unsigned char *JSAMPROW;
|
||||
|
||||
/* ptr to some rows (a 2-D sample array) */
|
||||
typedef JSAMPROW *JSAMPARRAY;
|
||||
|
||||
/* one block of coefficients */
|
||||
typedef signed char JBLOCK[DCTSIZE2];
|
||||
|
||||
/* pointer to one row of coefficient blocks */
|
||||
typedef JBLOCK *JBLOCKROW;
|
||||
|
||||
/* a 2-D array of coefficient blocks */
|
||||
typedef JBLOCKROW *JBLOCKARRAY;
|
||||
|
||||
/* useful in a couple of places */
|
||||
typedef signed char *JCOEFPTR;
|
||||
|
||||
/*
|
||||
DCT coefficient quantization tables.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* quantization step for each coefficient */
|
||||
/*
|
||||
This array gives the coefficient quantizers in natural array order (not
|
||||
the zigzag order in which they are stored in a JPEG DQT marker). CAUTION:
|
||||
IJG versions prior to v6a kept this array in zigzag order.
|
||||
*/
|
||||
unsigned short quantval[DCTSIZE2];
|
||||
|
||||
/* 1 when table has been output */
|
||||
/*
|
||||
This field is used only during compression. It's initialized 0 when the
|
||||
table is created, and set 1 when it's been output to the file. You could
|
||||
suppress output of a table by setting this to 1. (See jpeg_suppress_tables
|
||||
for an example.)
|
||||
*/
|
||||
int sent_table;
|
||||
} JQUANT_TBL;
|
||||
|
||||
/*
|
||||
Huffman coding tables.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* These two fields directly represent the contents of a JPEG DHT marker */
|
||||
|
||||
/* bits[k] = # of symbols with codes of */
|
||||
/* length k bits; bits[0] is unused */
|
||||
unsigned char bits[17];
|
||||
|
||||
/* The symbols, in order of incr code length */
|
||||
/*
|
||||
This field is used only during compression. It's initialized 0 when the
|
||||
table is created, and set 1 when it's been output to the file. You could
|
||||
suppress output of a table by setting this to 1. (See jpeg_suppress_tables
|
||||
for an example.)
|
||||
*/
|
||||
unsigned char huffval[256];
|
||||
|
||||
/* 1 when table has been output */
|
||||
int sent_table;
|
||||
} JHUFF_TBL;
|
||||
|
||||
/*
|
||||
Basic info about one component (color channel).
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
These values are fixed over the whole image. For compression, they must be
|
||||
supplied by parameter setup; for decompression, they are read from the SOF
|
||||
marker.
|
||||
*/
|
||||
|
||||
/* identifier for this component (0..255) */
|
||||
int component_id;
|
||||
|
||||
/* its index in SOF or cinfo->comp_info[] */
|
||||
int component_index;
|
||||
|
||||
/* horizontal sampling factor (1..4) */
|
||||
int h_samp_factor;
|
||||
|
||||
/* vertical sampling factor (1..4) */
|
||||
int v_samp_factor;
|
||||
|
||||
/* quantization table selector (0..3) */
|
||||
int quant_tbl_no;
|
||||
|
||||
/*
|
||||
These values may vary between scans. For compression, they must be
|
||||
supplied by parameter setup; for decompression, they are read from the SOS
|
||||
marker. The decompressor output side may not use these variables.
|
||||
*/
|
||||
|
||||
/* DC entropy table selector (0..3) */
|
||||
int dc_tbl_no;
|
||||
|
||||
/* AC entropy table selector (0..3) */
|
||||
int ac_tbl_no;
|
||||
|
||||
/* Remaining fields should be treated as private by applications. */
|
||||
|
||||
/*
|
||||
These values are computed during compression or decompression startup:
|
||||
Component's size in DCT blocks. Any dummy blocks added to complete an MCU
|
||||
are not counted; therefore these values do not depend on whether a scan is
|
||||
interleaved or not.
|
||||
*/
|
||||
unsigned int width_in_blocks;
|
||||
unsigned int height_in_blocks;
|
||||
|
||||
/*
|
||||
Size of a DCT block in samples. Always DCTSIZE for compression. For
|
||||
decompression this is the size of the output from one DCT block,
|
||||
reflecting any scaling we choose to apply during the IDCT step. Values of
|
||||
1,2,4,8 are likely to be supported. Note that different components may
|
||||
receive different IDCT scalings.
|
||||
*/
|
||||
int DCT_scaled_size;
|
||||
|
||||
/*
|
||||
The downsampled dimensions are the component's actual, unpadded number of
|
||||
samples at the main buffer (preprocessing/compression interface), thus
|
||||
downsampled_width = ceil(image_width * Hi/Hmax) and similarly for height.
|
||||
For decompression, IDCT scaling is included, so
|
||||
downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
|
||||
*/
|
||||
|
||||
/* actual width in samples */
|
||||
unsigned int downsampled_width;
|
||||
|
||||
/* actual height in samples */
|
||||
unsigned int downsampled_height;
|
||||
|
||||
/*
|
||||
This flag is used only for decompression. In cases where some of the
|
||||
components will be ignored (eg grayscale output from YCbCr image), we can
|
||||
skip most computations for the unused components.
|
||||
*/
|
||||
|
||||
/* do we need the value of this component? */
|
||||
int component_needed;
|
||||
|
||||
/*
|
||||
These values are computed before starting a scan of the component. The
|
||||
decompressor output side may not use these variables.
|
||||
*/
|
||||
|
||||
/* number of blocks per MCU, horizontally */
|
||||
int MCU_width;
|
||||
|
||||
/* number of blocks per MCU, vertically */
|
||||
int MCU_height;
|
||||
|
||||
/* MCU_width * MCU_height */
|
||||
int MCU_blocks;
|
||||
|
||||
/* MCU width in samples, MCU_width*DCT_scaled_size */
|
||||
int MCU_sample_width;
|
||||
|
||||
/* # of non-dummy blocks across in last MCU */
|
||||
int last_col_width;
|
||||
|
||||
/* # of non-dummy blocks down in last MCU */
|
||||
int last_row_height;
|
||||
|
||||
/*
|
||||
Saved quantization table for component; (void*)0 if none yet saved. See
|
||||
jdinput.c comments about the need for this information. This field is
|
||||
currently used only for decompression.
|
||||
*/
|
||||
JQUANT_TBL *quant_table;
|
||||
|
||||
/* Private per-component storage for DCT or IDCT subsystem. */
|
||||
void *dct_table;
|
||||
} jpeg_component_info;
|
||||
|
||||
/*
|
||||
The script for encoding a multiple-scan file is an array of these:
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* number of components encoded in this scan */
|
||||
int comps_in_scan;
|
||||
|
||||
/* their SOF/comp_info[] indexes */
|
||||
int component_index[4];
|
||||
|
||||
/* progressive JPEG spectral selection parms */
|
||||
int Ss, Se;
|
||||
|
||||
/* progressive JPEG successive approx. parms */
|
||||
int Ah, Al;
|
||||
} jpeg_scan_info;
|
||||
|
||||
/*
|
||||
Known color spaces.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* error/unspecified */
|
||||
JCS_UNKNOWN,
|
||||
|
||||
/* monochrome */
|
||||
JCS_GRAYSCALE,
|
||||
|
||||
/* red/green/blue */
|
||||
JCS_RGB,
|
||||
|
||||
/* Y/Cb/Cr (also known as YUV) */
|
||||
JCS_YCbCr,
|
||||
|
||||
/* C/M/Y/K */
|
||||
JCS_CMYK,
|
||||
|
||||
/* Y/Cb/Cr/K */
|
||||
JCS_YCCK
|
||||
} J_COLOR_SPACE;
|
||||
|
||||
/*
|
||||
DCT/IDCT algorithm options.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* slow but accurate integer algorithm */
|
||||
JDCT_ISLOW,
|
||||
|
||||
/* faster, less accurate integer method */
|
||||
JDCT_IFAST,
|
||||
|
||||
/* floating-point: accurate, fast on fast HW */
|
||||
JDCT_FLOAT
|
||||
} J_DCT_METHOD;
|
||||
|
||||
/*
|
||||
Common fields between JPEG compression and decompression master structs.
|
||||
*/
|
||||
|
||||
#define jpeg_common_fields \
|
||||
/* Error handler module */ \
|
||||
struct jpeg_error_mgr *err; \
|
||||
/* Memory manager module */ \
|
||||
struct jpeg_memory_mgr *mem; \
|
||||
/* Progress monitor, or (void*)0 if none */ \
|
||||
struct jpeg_progress_mgr *progress; \
|
||||
/* Available for use by application */ \
|
||||
void *client_data; \
|
||||
/* So common code can tell which is which */ \
|
||||
int is_decompressor; \
|
||||
/* For checking call sequence validity */ \
|
||||
int global_state
|
||||
|
||||
/*
|
||||
Routines that are to be used by both halves of the library are declared to
|
||||
receive a pointer to this structure. There are no actual instances of
|
||||
jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
|
||||
*/
|
||||
|
||||
struct jpeg_common_struct {
|
||||
/* Fields common to both master struct types */
|
||||
jpeg_common_fields;
|
||||
|
||||
/*
|
||||
Additional fields follow in an actual jpeg_compress_struct or
|
||||
jpeg_decompress_struct. All three structs must agree on these initial
|
||||
fields! (This would be a lot cleaner in C++.)
|
||||
*/
|
||||
};
|
||||
|
||||
typedef struct jpeg_common_struct *j_common_ptr;
|
||||
typedef struct jpeg_compress_struct *j_compress_ptr;
|
||||
typedef struct jpeg_decompress_struct *j_decompress_ptr;
|
||||
|
||||
/*
|
||||
Master record for a compression instance
|
||||
*/
|
||||
|
||||
struct jpeg_compress_struct {
|
||||
/* Fields shared with jpeg_decompress_struct */
|
||||
jpeg_common_fields;
|
||||
|
||||
/* Destination for compressed data */
|
||||
struct jpeg_destination_mgr *dest;
|
||||
|
||||
/*
|
||||
Description of source image --- these fields must be filled in by outer
|
||||
application before starting compression. in_color_space must be correct
|
||||
before you can even call jpeg_set_defaults().
|
||||
*/
|
||||
|
||||
/* input image width */
|
||||
unsigned int image_width;
|
||||
|
||||
/* input image height */
|
||||
unsigned int image_height;
|
||||
|
||||
/* # of color components in input image */
|
||||
int input_components;
|
||||
|
||||
/* colorspace of input image */
|
||||
J_COLOR_SPACE in_color_space;
|
||||
|
||||
/* image gamma of input image */
|
||||
double input_gamma;
|
||||
|
||||
/*
|
||||
Compression parameters --- these fields must be set before calling
|
||||
jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
|
||||
initialize everything to reasonable defaults, then changing anything the
|
||||
application specifically wants to change. That way you won't get burnt
|
||||
when new parameters are added. Also note that there are several helper
|
||||
routines to simplify changing parameters.
|
||||
*/
|
||||
|
||||
/* bits of precision in image data */
|
||||
int data_precision;
|
||||
|
||||
/* # of color components in JPEG image */
|
||||
int num_components;
|
||||
|
||||
/* colorspace of JPEG image */
|
||||
J_COLOR_SPACE jpeg_color_space;
|
||||
|
||||
/* comp_info[i] describes component that appears i'th in SOF */
|
||||
jpeg_component_info *comp_info;
|
||||
|
||||
/* ptrs to coefficient quantization tables, or (void*)0 if not defined */
|
||||
JQUANT_TBL *quant_tbl_ptrs[4];
|
||||
|
||||
/* ptrs to Huffman coding tables, or (void*)0 if not defined */
|
||||
JHUFF_TBL *dc_huff_tbl_ptrs[4];
|
||||
JHUFF_TBL *ac_huff_tbl_ptrs[4];
|
||||
|
||||
/* L values for DC arith-coding tables */
|
||||
unsigned char arith_dc_L[16];
|
||||
|
||||
/* U values for DC arith-coding tables */
|
||||
unsigned char arith_dc_U[16];
|
||||
|
||||
/* Kx values for AC arith-coding tables */
|
||||
unsigned char arith_ac_K[16];
|
||||
|
||||
/* # of entries in scan_info array */
|
||||
int num_scans;
|
||||
|
||||
/*
|
||||
script for multi-scan file, or (void*)0
|
||||
The default value of scan_info is (void*)0, which causes a single-scan
|
||||
sequential JPEG file to be emitted. To create a multi-scan file, set
|
||||
num_scans and scan_info to point to an array of scan definitions.
|
||||
*/
|
||||
const jpeg_scan_info *scan_info;
|
||||
|
||||
/* 1=caller supplies downsampled data */
|
||||
int raw_data_in;
|
||||
|
||||
/* 1=arithmetic coding, 0=Huffman */
|
||||
int arith_code;
|
||||
|
||||
/* 1=optimize entropy encoding parms */
|
||||
int optimize_coding;
|
||||
|
||||
/* 1=first samples are cosited */
|
||||
int CCIR601_sampling;
|
||||
|
||||
/* 1..100, or 0 for no input smoothing */
|
||||
int smoothing_factor;
|
||||
|
||||
/* DCT algorithm selector */
|
||||
J_DCT_METHOD dct_method;
|
||||
|
||||
/*
|
||||
The restart interval can be specified in absolute MCUs by setting
|
||||
restart_interval, or in MCU rows by setting restart_in_rows (in which case
|
||||
the correct restart_interval will be figured for each scan).
|
||||
*/
|
||||
|
||||
/* MCUs per restart, or 0 for no restart */
|
||||
unsigned int restart_interval;
|
||||
|
||||
/* if > 0, MCU rows per restart interval */
|
||||
int restart_in_rows;
|
||||
|
||||
/*
|
||||
Parameters controlling emission of special markers.
|
||||
*/
|
||||
|
||||
/* should a JFIF marker be written? */
|
||||
int write_JFIF_header;
|
||||
|
||||
/* What to write for the JFIF version number */
|
||||
unsigned char JFIF_major_version;
|
||||
unsigned char JFIF_minor_version;
|
||||
|
||||
/*
|
||||
These three values are not used by the JPEG code, merely copied into the
|
||||
JFIF APP0 marker. density_unit can be 0 for unknown, 1 for dots/inch, or
|
||||
2 for dots/cm. Note that the pixel aspect ratio is defined by
|
||||
X_density/Y_density even when density_unit=0.
|
||||
*/
|
||||
|
||||
/* JFIF code for pixel size units */
|
||||
unsigned char density_unit;
|
||||
|
||||
/* Horizontal pixel density */
|
||||
unsigned short X_density;
|
||||
|
||||
/* Vertical pixel density */
|
||||
unsigned short Y_density;
|
||||
|
||||
/* should an Adobe marker be written? */
|
||||
int write_Adobe_marker;
|
||||
|
||||
/*
|
||||
State variable: index of next scanline to be written to
|
||||
jpeg_write_scanlines(). Application may use this to control its processing
|
||||
loop, e.g., "while (next_scanline < image_height)".
|
||||
*/
|
||||
|
||||
/* 0 .. image_height-1 */
|
||||
unsigned int next_scanline;
|
||||
|
||||
/*
|
||||
Remaining fields are known throughout compressor, but generally should not
|
||||
be touched by a surrounding application.
|
||||
*/
|
||||
|
||||
/*
|
||||
These fields are computed during compression startup
|
||||
*/
|
||||
|
||||
/* 1 if scan script uses progressive mode */
|
||||
int progressive_mode;
|
||||
|
||||
/* largest h_samp_factor */
|
||||
int max_h_samp_factor;
|
||||
|
||||
/* largest v_samp_factor */
|
||||
int max_v_samp_factor;
|
||||
|
||||
/*
|
||||
# of iMCU rows to be input to coef ctlr
|
||||
The coefficient controller receives data in units of MCU rows as defined
|
||||
for fully interleaved scans (whether the JPEG file is interleaved or not).
|
||||
There are v_samp_factor * DCTSIZE sample rows of each component in an
|
||||
"iMCU" (interleaved MCU) row.
|
||||
*/
|
||||
unsigned int total_iMCU_rows;
|
||||
|
||||
/*
|
||||
These fields are valid during any one scan. They describe the components
|
||||
and MCUs actually appearing in the scan.
|
||||
*/
|
||||
|
||||
/* # of JPEG components in this scan */
|
||||
int comps_in_scan;
|
||||
|
||||
/* *cur_comp_info[i] describes component that appears i'th in SOS */
|
||||
jpeg_component_info *cur_comp_info[4];
|
||||
|
||||
/* # of MCUs across the image */
|
||||
unsigned int MCUs_per_row;
|
||||
|
||||
/* # of MCU rows in the image */
|
||||
unsigned int MCU_rows_in_scan;
|
||||
|
||||
/* # of DCT blocks per MCU */
|
||||
int blocks_in_MCU;
|
||||
|
||||
/*
|
||||
MCU_membership[i] is index in cur_comp_info of component owning i'th block
|
||||
in an MCU
|
||||
*/
|
||||
int MCU_membership[10];
|
||||
|
||||
/* progressive JPEG parameters for scan */
|
||||
int Ss, Se, Ah, Al;
|
||||
|
||||
/*
|
||||
Links to compression subobjects (methods and private variables of
|
||||
modules)
|
||||
*/
|
||||
|
||||
struct jpeg_comp_master *master;
|
||||
struct jpeg_c_main_controller *main;
|
||||
struct jpeg_c_prep_controller *prep;
|
||||
struct jpeg_c_coef_controller *coef;
|
||||
struct jpeg_marker_writer *marker;
|
||||
struct jpeg_color_converter *cconvert;
|
||||
struct jpeg_downsampler *downsample;
|
||||
struct jpeg_forward_dct *fdct;
|
||||
struct jpeg_entropy_encoder *entropy;
|
||||
|
||||
/* workspace for jpeg_simple_progression */
|
||||
jpeg_scan_info *script_space;
|
||||
|
||||
int script_space_size;
|
||||
};
|
||||
|
||||
/*
|
||||
"Object" declarations for JPEG modules that may be supplied or called directly
|
||||
by the surrounding application. As with all objects in the JPEG library, these
|
||||
structs only define the publicly visible methods and state variables of a
|
||||
module. Additional private fields may exist after the public ones.
|
||||
*/
|
||||
|
||||
/*
|
||||
Error handler object
|
||||
*/
|
||||
|
||||
struct jpeg_error_mgr {
|
||||
/* Error exit handler: does not return to caller */
|
||||
void (*error_exit)(j_common_ptr cinfo);
|
||||
|
||||
/* Conditionally emit a trace or warning message */
|
||||
void (*emit_message)(j_common_ptr cinfo, int msg_level);
|
||||
|
||||
/* Routine that actually outputs a trace or error message */
|
||||
void (*output_message)(j_common_ptr cinfo);
|
||||
|
||||
/* Format a message string for the most recent JPEG error or message */
|
||||
void (*format_message)(j_common_ptr cinfo, char *buffer);
|
||||
|
||||
/* Reset error state variables at start of a new image */
|
||||
void (*reset_error_mgr)(j_common_ptr cinfo);
|
||||
|
||||
/*
|
||||
The message ID code and any parameters are saved here. A message can have
|
||||
one string parameter or up to 8 int parameters.
|
||||
*/
|
||||
int msg_code;
|
||||
|
||||
union {
|
||||
int i[8];
|
||||
char s[80];
|
||||
} msg_parm;
|
||||
|
||||
/*
|
||||
Standard state variables for error facility
|
||||
*/
|
||||
|
||||
/* max msg_level that will be displayed */
|
||||
int trace_level;
|
||||
|
||||
/*
|
||||
For recoverable corrupt-data errors, we emit a warning message, but keep
|
||||
going unless emit_message chooses to abort. emit_message should count
|
||||
warnings in num_warnings. The surrounding application can check for bad
|
||||
data by seeing if num_warnings is nonzero at the end of processing.
|
||||
*/
|
||||
|
||||
/* number of corrupt-data warnings */
|
||||
long num_warnings;
|
||||
|
||||
/*
|
||||
These fields point to the table(s) of error message strings. An
|
||||
application can change the table pointer to switch to a different message
|
||||
list (typically, to change the language in which errors are reported).
|
||||
Some applications may wish to add additional error codes that will be
|
||||
handled by the JPEG library error mechanism; the second table pointer is
|
||||
used for this purpose.
|
||||
|
||||
First table includes all errors generated by JPEG library itself. Error
|
||||
code 0 is reserved for a "no such error string" message.
|
||||
*/
|
||||
|
||||
/* Library errors */
|
||||
const char *const *jpeg_message_table;
|
||||
|
||||
/* Table contains strings 0..last_jpeg_message */
|
||||
int last_jpeg_message;
|
||||
|
||||
/*
|
||||
Second table can be added by application (see cjpeg/djpeg for example). It
|
||||
contains strings numbered first_addon_message..last_addon_message.
|
||||
*/
|
||||
|
||||
/* Non-library errors */
|
||||
const char *const *addon_message_table;
|
||||
|
||||
/* code for first string in addon table */
|
||||
int first_addon_message;
|
||||
|
||||
/* code for last string in addon table */
|
||||
int last_addon_message;
|
||||
};
|
||||
|
||||
/*
|
||||
Progress monitor object
|
||||
*/
|
||||
|
||||
struct jpeg_progress_mgr {
|
||||
void (*progress_monitor)(j_common_ptr cinfo);
|
||||
|
||||
/* work units completed in this pass */
|
||||
long pass_counter;
|
||||
|
||||
/* total number of work units in this pass */
|
||||
long pass_limit;
|
||||
|
||||
/* passes completed so far */
|
||||
int completed_passes;
|
||||
|
||||
/* total number of passes expected */
|
||||
int total_passes;
|
||||
};
|
||||
|
||||
/*
|
||||
Data destination object for compression
|
||||
*/
|
||||
|
||||
struct jpeg_destination_mgr {
|
||||
/* => next byte to write in buffer */
|
||||
unsigned char *next_output_byte;
|
||||
|
||||
/* # of byte spaces remaining in buffer */
|
||||
long unsigned int free_in_buffer;
|
||||
|
||||
void (*init_destination)(j_compress_ptr cinfo);
|
||||
int (*empty_output_buffer)(j_compress_ptr cinfo);
|
||||
void (*term_destination)(j_compress_ptr cinfo);
|
||||
};
|
||||
|
||||
/*
|
||||
Memory manager object.
|
||||
Allocates "small" objects (a few K total), "large" objects (tens of K), and
|
||||
"really big" objects (virtual arrays with backing store if needed). The memory
|
||||
manager does not allow individual objects to be freed; rather, each created
|
||||
object is assigned to a pool, and whole pools can be freed at once. This is
|
||||
faster and more convenient than remembering exactly what to free, especially
|
||||
where malloc()/free() are not too speedy.
|
||||
NB: alloc routines never return (void*)0. They exit to error_exit if not
|
||||
successful.
|
||||
*/
|
||||
|
||||
typedef struct jvirt_sarray_control *jvirt_sarray_ptr;
|
||||
typedef struct jvirt_barray_control *jvirt_barray_ptr;
|
||||
|
||||
struct jpeg_memory_mgr {
|
||||
/*
|
||||
Method pointers
|
||||
*/
|
||||
void *(*alloc_small)(j_common_ptr cinfo, int pool_id,
|
||||
long unsigned int sizeofobject);
|
||||
|
||||
void *(*alloc_large)(j_common_ptr cinfo, int pool_id,
|
||||
long unsigned int sizeofobject);
|
||||
|
||||
JSAMPARRAY (*alloc_sarray)(j_common_ptr cinfo, int pool_id,
|
||||
unsigned int samplesperrow,
|
||||
unsigned int numrows);
|
||||
|
||||
JBLOCKARRAY (*alloc_barray)(j_common_ptr cinfo, int pool_id,
|
||||
unsigned int blocksperrow,
|
||||
unsigned int numrows);
|
||||
|
||||
jvirt_sarray_ptr (*request_virt_sarray)(j_common_ptr cinfo, int pool_id,
|
||||
int pre_zero,
|
||||
unsigned int samplesperrow,
|
||||
unsigned int numrows,
|
||||
unsigned int maxaccess);
|
||||
|
||||
jvirt_barray_ptr (*request_virt_barray)(j_common_ptr cinfo, int pool_id,
|
||||
int pre_zero,
|
||||
unsigned int blocksperrow,
|
||||
unsigned int numrows,
|
||||
unsigned int maxaccess);
|
||||
|
||||
void (*realize_virt_arrays)(j_common_ptr cinfo);
|
||||
|
||||
JSAMPARRAY (*access_virt_sarray)(j_common_ptr cinfo, jvirt_sarray_ptr ptr,
|
||||
unsigned int start_row,
|
||||
unsigned int num_rows, int writable);
|
||||
|
||||
JBLOCKARRAY (*access_virt_barray)(j_common_ptr cinfo, jvirt_barray_ptr ptr,
|
||||
unsigned int start_row,
|
||||
unsigned int num_rows, int writable);
|
||||
|
||||
void (*free_pool)(j_common_ptr cinfo, int pool_id);
|
||||
|
||||
void (*self_destruct)(j_common_ptr cinfo);
|
||||
|
||||
/*
|
||||
Limit on memory allocation for this JPEG object. (Note that this is merely
|
||||
advisory, not a guaranteed maximum; it only affects the space used for
|
||||
virtual-array buffers.) May be changed by outer application after creating
|
||||
the JPEG object.
|
||||
*/
|
||||
long max_memory_to_use;
|
||||
|
||||
/* Maximum allocation request accepted by alloc_large. */
|
||||
long max_alloc_chunk;
|
||||
};
|
||||
|
||||
#endif /* JPEGLIB_H */
|
||||
@ -0,0 +1,757 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: cjpeg_transupp
|
||||
|
||||
Author: Thomas G. Lane
|
||||
|
||||
Function: This file contains image transformation routines and other utility
|
||||
code used by the jpegtran sample application. These are NOT part of the core
|
||||
JPEG library. But we keep these routines separate from jpegtran.c to ease
|
||||
the task of maintaining jpegtran-like programs that have other user
|
||||
interfaces.
|
||||
|
||||
Source: MediaBench II
|
||||
http://euler.slu.edu/~fritts/mediabench (mirror)
|
||||
|
||||
Original name: cjpeg
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the accompanying README file.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Include section
|
||||
*/
|
||||
|
||||
#include "jpeglib.h"
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
|
||||
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
__attribute__((always_inline)) static inline void cjpeg_transupp_initSeed(void);
|
||||
__attribute__((always_inline)) static inline signed char
|
||||
cjpeg_transupp_randomInteger(void);
|
||||
__attribute__((always_inline)) static inline void cjpeg_transupp_init(void);
|
||||
__attribute__((always_inline)) static inline int cjpeg_transupp_return(void);
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_flip_v(j_compress_ptr);
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_rot_90(j_compress_ptr);
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_rot_180(j_compress_ptr);
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_rot_270(j_compress_ptr);
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_transverse(j_compress_ptr);
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
cjpeg_transupp_main(void);
|
||||
__attribute__((noinline)) __attribute__((export_name("main")))
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void);
|
||||
|
||||
/*
|
||||
Declaration of global variables
|
||||
*/
|
||||
|
||||
volatile int cjpeg_transupp_seed;
|
||||
|
||||
signed char cjpeg_transupp_input[256];
|
||||
signed char cjpeg_transupp_input2[80];
|
||||
signed char cjpeg_transupp_input3[65];
|
||||
signed char cjpeg_transupp_input3_2[65];
|
||||
signed char cjpeg_transupp_input4[64];
|
||||
signed char cjpeg_transupp_input5[65];
|
||||
signed char cjpeg_transupp_input5_2[65];
|
||||
|
||||
/* Output arrays replace writing of results into a file. */
|
||||
signed char cjpeg_transupp_output_data[512];
|
||||
signed char cjpeg_transupp_output_data2[512];
|
||||
signed char cjpeg_transupp_output_data3[512];
|
||||
signed char cjpeg_transupp_output_data4[512];
|
||||
signed char cjpeg_transupp_output_data5[512];
|
||||
|
||||
struct jpeg_compress_struct cjpeg_transupp_dstinfo;
|
||||
|
||||
/*
|
||||
Initialization- and return-value-related functions
|
||||
*/
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_initSeed(void) {
|
||||
cjpeg_transupp_seed = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
cjpeg_transupp_RandomInteger generates random integers between -128 and 127.
|
||||
*/
|
||||
__attribute__((always_inline)) static inline signed char
|
||||
cjpeg_transupp_randomInteger(void) {
|
||||
cjpeg_transupp_seed = (((cjpeg_transupp_seed * 133) + 81) % 256) - 128;
|
||||
return (cjpeg_transupp_seed);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_init(void) {
|
||||
register int i;
|
||||
|
||||
cjpeg_transupp_dstinfo.max_h_samp_factor = 2;
|
||||
cjpeg_transupp_dstinfo.max_v_samp_factor = 2;
|
||||
cjpeg_transupp_dstinfo.num_components = 3;
|
||||
|
||||
cjpeg_transupp_initSeed();
|
||||
|
||||
__pragma_loopbound(256, 256);
|
||||
for (i = 0; i < 256; i++)
|
||||
cjpeg_transupp_input[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(80, 80);
|
||||
for (i = 0; i < 80; i++)
|
||||
cjpeg_transupp_input2[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(65, 65);
|
||||
for (i = 0; i < 65; i++)
|
||||
cjpeg_transupp_input3[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(65, 65);
|
||||
for (i = 0; i < 65; i++)
|
||||
cjpeg_transupp_input3_2[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(64, 64);
|
||||
for (i = 0; i < 64; i++)
|
||||
cjpeg_transupp_input4[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(65, 65);
|
||||
for (i = 0; i < 65; i++)
|
||||
cjpeg_transupp_input5[i] = cjpeg_transupp_randomInteger();
|
||||
|
||||
__pragma_loopbound(65, 65);
|
||||
for (i = 0; i < 65; i++)
|
||||
cjpeg_transupp_input5_2[i] = cjpeg_transupp_randomInteger();
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline int
|
||||
cjpeg_transupp_return(void) {
|
||||
int checksum = 0;
|
||||
unsigned int i;
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data[i];
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data2[i];
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data3[i];
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data4[i];
|
||||
|
||||
__pragma_loopbound(512, 512);
|
||||
for (i = 0; i < 512; i++)
|
||||
checksum += cjpeg_transupp_output_data5[i];
|
||||
|
||||
return (checksum);
|
||||
}
|
||||
|
||||
/*
|
||||
Algorithm core functions
|
||||
*/
|
||||
|
||||
/*
|
||||
Vertical flip
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_flip_v(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
/*
|
||||
We output into a separate array because we can't touch different rows of
|
||||
the source virtual array simultaneously. Otherwise, this is a pretty
|
||||
straightforward analog of horizontal flip.
|
||||
Within a DCT block, vertical mirroring is done by changing the signs of
|
||||
odd-numbered rows.
|
||||
Partial iMCUs at the bottom edge are copied verbatim.
|
||||
*/
|
||||
MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
|
||||
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 19;
|
||||
unsigned int compptr_width_in_blocks = 29;
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components;
|
||||
ci++, compptr_v_samp_factor = 1, compptr_width_in_blocks = 15) {
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
compptr_height_in_blocks = 10;
|
||||
_Pragma(
|
||||
"loopbound min 2 max 10") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
|
||||
__pragma_loopbound(1, 8);
|
||||
for (offset_y = 0; offset_y < compptr_v_samp_factor; offset_y++) {
|
||||
if (dst_blk_y < comp_height) {
|
||||
|
||||
/* Row is within the mirrorable area. */
|
||||
_Pragma(
|
||||
"loopbound min 15 max 29") for (dst_blk_x = 0;
|
||||
dst_blk_x <
|
||||
compptr_width_in_blocks;
|
||||
dst_blk_x++) {
|
||||
|
||||
src_ptr = cjpeg_transupp_input;
|
||||
dst_ptr = cjpeg_transupp_output_data;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i += 2) {
|
||||
|
||||
/* copy even row */
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
do {
|
||||
if (dst_blk_x < comp_height)
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
j++;
|
||||
} while (j < DCTSIZE);
|
||||
|
||||
/* copy odd row with sign change */
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
do {
|
||||
if (dst_blk_x < comp_height)
|
||||
*dst_ptr++ = -*src_ptr++;
|
||||
j++;
|
||||
} while (j < DCTSIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
90 degree rotation is equivalent to
|
||||
1. Transposing the image;
|
||||
2. Horizontal mirroring.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_rot_90(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_cols, comp_width, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
/*
|
||||
Because of the horizontal mirror step, we can't process partial iMCUs at
|
||||
the (output) right edge properly. They just get transposed and not
|
||||
mirrored.
|
||||
*/
|
||||
MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 4 max 15") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
|
||||
offset_y = 0;
|
||||
__pragma_loopbound(1, 8);
|
||||
for (; offset_y < compptr_v_samp_factor; offset_y++) {
|
||||
dst_blk_x = 0;
|
||||
__pragma_loopbound(10, 10);
|
||||
for (; dst_blk_x < compptr_width_in_blocks;
|
||||
dst_blk_x += compptr_h_samp_factor) {
|
||||
|
||||
offset_x = 0;
|
||||
__pragma_loopbound(1, 2);
|
||||
for (; offset_x < compptr_h_samp_factor; offset_x++) {
|
||||
|
||||
src_ptr = cjpeg_transupp_input2;
|
||||
|
||||
if (dst_blk_x < comp_width) {
|
||||
|
||||
/* Block is within the mirrorable area. */
|
||||
dst_ptr = cjpeg_transupp_output_data2;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (; j < DCTSIZE; j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
|
||||
i++;
|
||||
|
||||
__pragma_loopbound(8, 8);
|
||||
for (j = 0; j < DCTSIZE; j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
} else {
|
||||
/* Edge blocks are transposed but not mirrored. */
|
||||
dst_ptr = cjpeg_transupp_output_data2;
|
||||
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++)
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (; j < DCTSIZE; j++) {
|
||||
if (dst_blk_y < comp_width)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
270 degree rotation is equivalent to
|
||||
1. Horizontal mirroring;
|
||||
2. Transposing the image.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_rot_270(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
/*
|
||||
Because of the horizontal mirror step, we can't process partial iMCUs at
|
||||
the (output) bottom edge properly. They just get transposed and not
|
||||
mirrored.
|
||||
*/
|
||||
MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10) {
|
||||
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 4 max 15") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
|
||||
offset_y = 0;
|
||||
__pragma_loopbound(1, 8);
|
||||
for (; offset_y < compptr_v_samp_factor; offset_y++) {
|
||||
dst_blk_x = 0;
|
||||
__pragma_loopbound(10, 10);
|
||||
for (; dst_blk_x < compptr_width_in_blocks;
|
||||
dst_blk_x += compptr_h_samp_factor) {
|
||||
|
||||
offset_x = 0;
|
||||
__pragma_loopbound(1, 2);
|
||||
for (; offset_x < compptr_h_samp_factor; offset_x++) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data3;
|
||||
|
||||
if (dst_blk_y < comp_height) {
|
||||
|
||||
/* Block is within the mirrorable area. */
|
||||
src_ptr = cjpeg_transupp_input3;
|
||||
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
__pragma_loopbound(4, 4);
|
||||
for (; j < DCTSIZE; j++) {
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
j++;
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/* Edge blocks are transposed but not mirrored. */
|
||||
src_ptr = cjpeg_transupp_input3_2;
|
||||
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++)
|
||||
j = 0;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (; j < DCTSIZE; j++) {
|
||||
if (dst_blk_y < comp_height)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
180 degree rotation is equivalent to
|
||||
1. Vertical mirroring;
|
||||
2. Horizontal mirroring.
|
||||
These two steps are merged into a single processing routine.
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_rot_180(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x,
|
||||
dst_blk_y;
|
||||
int ci, i, j, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_width_in_blocks = 29;
|
||||
unsigned int compptr_height_in_blocks = 19;
|
||||
|
||||
MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
|
||||
MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_width_in_blocks = 15, compptr_height_in_blocks = 10) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 3 max 10") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
offset_y = 0;
|
||||
__pragma_loopbound(1, 8);
|
||||
for (; offset_y < compptr_v_samp_factor; offset_y++) {
|
||||
if (dst_blk_y < comp_height) {
|
||||
|
||||
/* Row is within the mirrorable area. */
|
||||
|
||||
/* Process the blocks that can be mirrored both ways. */
|
||||
__pragma_loopbound(14, 28);
|
||||
for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i += 2) {
|
||||
j = 0;
|
||||
/* For even row, negate every odd column. */
|
||||
__pragma_loopbound(4, 4);
|
||||
for (; j < DCTSIZE; j += 2) {
|
||||
if (dst_blk_x < comp_height) {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
*dst_ptr++ = -*src_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
/* For odd row, negate every even column. */
|
||||
__pragma_loopbound(4, 4);
|
||||
for (; j < DCTSIZE; j += 2) {
|
||||
if (dst_blk_x < comp_height) {
|
||||
*dst_ptr++ = -*src_ptr++;
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Any remaining right-edge blocks are only mirrored
|
||||
* vertically. */
|
||||
_Pragma(
|
||||
"loopbound min 1 max 1") for (; dst_blk_x <
|
||||
compptr_width_in_blocks;
|
||||
dst_blk_x++) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i += 2) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (; j < DCTSIZE;
|
||||
j++) *dst_ptr++ =
|
||||
*src_ptr++;
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (; j < DCTSIZE;
|
||||
j++) *dst_ptr++ =
|
||||
-*src_ptr++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/* Remaining rows are just mirrored horizontally. */
|
||||
dst_blk_x = 0;
|
||||
/* Process the blocks that can be mirrored. */
|
||||
__pragma_loopbound(14, 14);
|
||||
do {
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
|
||||
i = 0;
|
||||
__pragma_loopbound(32, 32);
|
||||
while (i < DCTSIZE2) {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
*dst_ptr++ = -*src_ptr++;
|
||||
i += 2;
|
||||
dst_ptr += 0;
|
||||
}
|
||||
dst_blk_x++;
|
||||
dst_ptr += 0;
|
||||
} while (dst_blk_x < comp_width);
|
||||
|
||||
/* Any remaining right-edge blocks are only copied. */
|
||||
_Pragma(
|
||||
"loopbound min 1 max 1") for (; dst_blk_x <
|
||||
compptr_width_in_blocks;
|
||||
dst_blk_x++) {
|
||||
|
||||
dst_ptr = cjpeg_transupp_output_data4;
|
||||
src_ptr = cjpeg_transupp_input4;
|
||||
__pragma_loopbound(1, 1);
|
||||
do {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
i++;
|
||||
} while (i < DCTSIZE2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Transverse transpose is equivalent to
|
||||
1. 180 degree rotation;
|
||||
2. Transposition;
|
||||
or
|
||||
1. Horizontal mirroring;
|
||||
2. Transposition;
|
||||
3. Horizontal mirroring.
|
||||
These steps are merged into a single processing routine.
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void
|
||||
cjpeg_transupp_do_transverse(j_compress_ptr dstinfo) {
|
||||
unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x,
|
||||
dst_blk_y;
|
||||
int ci, i, j, offset_x, offset_y;
|
||||
JCOEFPTR src_ptr, dst_ptr;
|
||||
|
||||
int compptr_h_samp_factor = 2;
|
||||
int compptr_v_samp_factor = 8;
|
||||
unsigned int compptr_height_in_blocks = 29;
|
||||
unsigned int compptr_width_in_blocks = 19;
|
||||
|
||||
MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
|
||||
MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (ci = 0; ci < dstinfo->num_components; ci++,
|
||||
compptr_h_samp_factor = compptr_v_samp_factor = 1,
|
||||
compptr_height_in_blocks = 15, compptr_width_in_blocks = 10) {
|
||||
|
||||
comp_width = MCU_cols * compptr_h_samp_factor;
|
||||
comp_height = MCU_rows * compptr_v_samp_factor;
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 4 max 15") for (dst_blk_y = 0;
|
||||
dst_blk_y < compptr_height_in_blocks;
|
||||
dst_blk_y += compptr_v_samp_factor) {
|
||||
offset_y = 0;
|
||||
__pragma_loopbound(1, 8);
|
||||
do {
|
||||
dst_blk_x = 0;
|
||||
__pragma_loopbound(5, 10);
|
||||
do {
|
||||
offset_x = 0;
|
||||
__pragma_loopbound(1, 2);
|
||||
for (; offset_x < compptr_h_samp_factor; offset_x++) {
|
||||
|
||||
if (dst_blk_y < comp_height) {
|
||||
src_ptr = cjpeg_transupp_input5;
|
||||
|
||||
if (dst_blk_x < comp_width) {
|
||||
/* Block is within the mirrorable area. */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 4 max 4") for (; j <
|
||||
DCTSIZE;
|
||||
j++) {
|
||||
if (dst_blk_y < comp_width)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
j++;
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
i++;
|
||||
_Pragma(
|
||||
"loopbound min 4 max 4") for (j = 0;
|
||||
j <
|
||||
DCTSIZE;
|
||||
j++) {
|
||||
if (dst_blk_y < comp_width)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
j++;
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Right-edge blocks are mirrored in y only */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 4 max 4") for (; j <
|
||||
DCTSIZE;
|
||||
j++) {
|
||||
if (dst_blk_y < comp_width)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
j++;
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
src_ptr = cjpeg_transupp_input5_2;
|
||||
|
||||
if (dst_blk_x < comp_width) {
|
||||
/* Bottom-edge blocks are mirrored in x only */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
|
||||
__pragma_loopbound(4, 4);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (; j <
|
||||
DCTSIZE;
|
||||
j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
i++;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (j = 0;
|
||||
j <
|
||||
DCTSIZE;
|
||||
j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
-src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
} else {
|
||||
/* At lower right corner, just transpose, no
|
||||
* mirroring */
|
||||
dst_ptr = cjpeg_transupp_output_data5;
|
||||
__pragma_loopbound(8, 8);
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
j = 0;
|
||||
_Pragma(
|
||||
"loopbound min 8 max 8") for (; j <
|
||||
DCTSIZE;
|
||||
j++)
|
||||
dst_ptr[j * DCTSIZE + i] =
|
||||
src_ptr[i * DCTSIZE + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
dst_blk_x += compptr_h_samp_factor;
|
||||
}
|
||||
} while (dst_blk_x < compptr_width_in_blocks);
|
||||
offset_y++;
|
||||
} while (offset_y < compptr_v_samp_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Main functions
|
||||
*/
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
cjpeg_transupp_main(void) {
|
||||
cjpeg_transupp_dstinfo.image_width = 227;
|
||||
cjpeg_transupp_dstinfo.image_height = 149;
|
||||
|
||||
cjpeg_transupp_do_flip_v(&cjpeg_transupp_dstinfo);
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 149;
|
||||
cjpeg_transupp_dstinfo.image_height = 227;
|
||||
|
||||
cjpeg_transupp_do_rot_90(&cjpeg_transupp_dstinfo);
|
||||
cjpeg_transupp_do_rot_270(&cjpeg_transupp_dstinfo);
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 227;
|
||||
cjpeg_transupp_dstinfo.image_height = 149;
|
||||
|
||||
cjpeg_transupp_do_rot_180(&cjpeg_transupp_dstinfo);
|
||||
|
||||
cjpeg_transupp_dstinfo.image_width = 149;
|
||||
cjpeg_transupp_dstinfo.image_height = 227;
|
||||
|
||||
cjpeg_transupp_do_transverse(&cjpeg_transupp_dstinfo);
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("main")))
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void) {
|
||||
cjpeg_transupp_init();
|
||||
cjpeg_transupp_main();
|
||||
|
||||
return (cjpeg_transupp_return() - 1624 != 0);
|
||||
}
|
||||
@ -0,0 +1,743 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: jpeglib
|
||||
|
||||
Author: Thomas G. Lane
|
||||
|
||||
Function: This file defines the application interface for the JPEG library.
|
||||
Most applications using the library need only include this file, and perhaps
|
||||
jerror.h if they want to know the exact error codes.
|
||||
|
||||
Source: MediaBench II
|
||||
http://euler.slu.edu/~fritts/mediabench (mirror)
|
||||
|
||||
Original name: cjpeg
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the accompanying README file.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef JPEGLIB_H
|
||||
#define JPEGLIB_H
|
||||
|
||||
/*
|
||||
Various constants determining the sizes of things.
|
||||
All of these are specified by the JPEG standard, so don't change them if you
|
||||
want to be compatible.
|
||||
*/
|
||||
|
||||
/* The basic DCT block is 8x8 samples */
|
||||
#define DCTSIZE 8
|
||||
|
||||
/* DCTSIZE squared; # of elements in a block */
|
||||
#define DCTSIZE2 64
|
||||
|
||||
/*
|
||||
Data structures for images (arrays of samples and of DCT coefficients).
|
||||
On 80x86 machines, the image arrays are too big for near pointers, but the
|
||||
pointer arrays can fit in near memory.
|
||||
*/
|
||||
|
||||
/* ptr to one image row of pixel samples. */
|
||||
typedef unsigned char *JSAMPROW;
|
||||
|
||||
/* ptr to some rows (a 2-D sample array) */
|
||||
typedef JSAMPROW *JSAMPARRAY;
|
||||
|
||||
/* one block of coefficients */
|
||||
typedef signed char JBLOCK[DCTSIZE2];
|
||||
|
||||
/* pointer to one row of coefficient blocks */
|
||||
typedef JBLOCK *JBLOCKROW;
|
||||
|
||||
/* a 2-D array of coefficient blocks */
|
||||
typedef JBLOCKROW *JBLOCKARRAY;
|
||||
|
||||
/* useful in a couple of places */
|
||||
typedef signed char *JCOEFPTR;
|
||||
|
||||
/*
|
||||
DCT coefficient quantization tables.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* quantization step for each coefficient */
|
||||
/*
|
||||
This array gives the coefficient quantizers in natural array order (not
|
||||
the zigzag order in which they are stored in a JPEG DQT marker). CAUTION:
|
||||
IJG versions prior to v6a kept this array in zigzag order.
|
||||
*/
|
||||
unsigned short quantval[DCTSIZE2];
|
||||
|
||||
/* 1 when table has been output */
|
||||
/*
|
||||
This field is used only during compression. It's initialized 0 when the
|
||||
table is created, and set 1 when it's been output to the file. You could
|
||||
suppress output of a table by setting this to 1. (See jpeg_suppress_tables
|
||||
for an example.)
|
||||
*/
|
||||
int sent_table;
|
||||
} JQUANT_TBL;
|
||||
|
||||
/*
|
||||
Huffman coding tables.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* These two fields directly represent the contents of a JPEG DHT marker */
|
||||
|
||||
/* bits[k] = # of symbols with codes of */
|
||||
/* length k bits; bits[0] is unused */
|
||||
unsigned char bits[17];
|
||||
|
||||
/* The symbols, in order of incr code length */
|
||||
/*
|
||||
This field is used only during compression. It's initialized 0 when the
|
||||
table is created, and set 1 when it's been output to the file. You could
|
||||
suppress output of a table by setting this to 1. (See jpeg_suppress_tables
|
||||
for an example.)
|
||||
*/
|
||||
unsigned char huffval[256];
|
||||
|
||||
/* 1 when table has been output */
|
||||
int sent_table;
|
||||
} JHUFF_TBL;
|
||||
|
||||
/*
|
||||
Basic info about one component (color channel).
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
These values are fixed over the whole image. For compression, they must be
|
||||
supplied by parameter setup; for decompression, they are read from the SOF
|
||||
marker.
|
||||
*/
|
||||
|
||||
/* identifier for this component (0..255) */
|
||||
int component_id;
|
||||
|
||||
/* its index in SOF or cinfo->comp_info[] */
|
||||
int component_index;
|
||||
|
||||
/* horizontal sampling factor (1..4) */
|
||||
int h_samp_factor;
|
||||
|
||||
/* vertical sampling factor (1..4) */
|
||||
int v_samp_factor;
|
||||
|
||||
/* quantization table selector (0..3) */
|
||||
int quant_tbl_no;
|
||||
|
||||
/*
|
||||
These values may vary between scans. For compression, they must be
|
||||
supplied by parameter setup; for decompression, they are read from the SOS
|
||||
marker. The decompressor output side may not use these variables.
|
||||
*/
|
||||
|
||||
/* DC entropy table selector (0..3) */
|
||||
int dc_tbl_no;
|
||||
|
||||
/* AC entropy table selector (0..3) */
|
||||
int ac_tbl_no;
|
||||
|
||||
/* Remaining fields should be treated as private by applications. */
|
||||
|
||||
/*
|
||||
These values are computed during compression or decompression startup:
|
||||
Component's size in DCT blocks. Any dummy blocks added to complete an MCU
|
||||
are not counted; therefore these values do not depend on whether a scan is
|
||||
interleaved or not.
|
||||
*/
|
||||
unsigned int width_in_blocks;
|
||||
unsigned int height_in_blocks;
|
||||
|
||||
/*
|
||||
Size of a DCT block in samples. Always DCTSIZE for compression. For
|
||||
decompression this is the size of the output from one DCT block,
|
||||
reflecting any scaling we choose to apply during the IDCT step. Values of
|
||||
1,2,4,8 are likely to be supported. Note that different components may
|
||||
receive different IDCT scalings.
|
||||
*/
|
||||
int DCT_scaled_size;
|
||||
|
||||
/*
|
||||
The downsampled dimensions are the component's actual, unpadded number of
|
||||
samples at the main buffer (preprocessing/compression interface), thus
|
||||
downsampled_width = ceil(image_width * Hi/Hmax) and similarly for height.
|
||||
For decompression, IDCT scaling is included, so
|
||||
downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
|
||||
*/
|
||||
|
||||
/* actual width in samples */
|
||||
unsigned int downsampled_width;
|
||||
|
||||
/* actual height in samples */
|
||||
unsigned int downsampled_height;
|
||||
|
||||
/*
|
||||
This flag is used only for decompression. In cases where some of the
|
||||
components will be ignored (eg grayscale output from YCbCr image), we can
|
||||
skip most computations for the unused components.
|
||||
*/
|
||||
|
||||
/* do we need the value of this component? */
|
||||
int component_needed;
|
||||
|
||||
/*
|
||||
These values are computed before starting a scan of the component. The
|
||||
decompressor output side may not use these variables.
|
||||
*/
|
||||
|
||||
/* number of blocks per MCU, horizontally */
|
||||
int MCU_width;
|
||||
|
||||
/* number of blocks per MCU, vertically */
|
||||
int MCU_height;
|
||||
|
||||
/* MCU_width * MCU_height */
|
||||
int MCU_blocks;
|
||||
|
||||
/* MCU width in samples, MCU_width*DCT_scaled_size */
|
||||
int MCU_sample_width;
|
||||
|
||||
/* # of non-dummy blocks across in last MCU */
|
||||
int last_col_width;
|
||||
|
||||
/* # of non-dummy blocks down in last MCU */
|
||||
int last_row_height;
|
||||
|
||||
/*
|
||||
Saved quantization table for component; (void*)0 if none yet saved. See
|
||||
jdinput.c comments about the need for this information. This field is
|
||||
currently used only for decompression.
|
||||
*/
|
||||
JQUANT_TBL *quant_table;
|
||||
|
||||
/* Private per-component storage for DCT or IDCT subsystem. */
|
||||
void *dct_table;
|
||||
} jpeg_component_info;
|
||||
|
||||
/*
|
||||
The script for encoding a multiple-scan file is an array of these:
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* number of components encoded in this scan */
|
||||
int comps_in_scan;
|
||||
|
||||
/* their SOF/comp_info[] indexes */
|
||||
int component_index[4];
|
||||
|
||||
/* progressive JPEG spectral selection parms */
|
||||
int Ss, Se;
|
||||
|
||||
/* progressive JPEG successive approx. parms */
|
||||
int Ah, Al;
|
||||
} jpeg_scan_info;
|
||||
|
||||
/*
|
||||
Known color spaces.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* error/unspecified */
|
||||
JCS_UNKNOWN,
|
||||
|
||||
/* monochrome */
|
||||
JCS_GRAYSCALE,
|
||||
|
||||
/* red/green/blue */
|
||||
JCS_RGB,
|
||||
|
||||
/* Y/Cb/Cr (also known as YUV) */
|
||||
JCS_YCbCr,
|
||||
|
||||
/* C/M/Y/K */
|
||||
JCS_CMYK,
|
||||
|
||||
/* Y/Cb/Cr/K */
|
||||
JCS_YCCK
|
||||
} J_COLOR_SPACE;
|
||||
|
||||
/*
|
||||
DCT/IDCT algorithm options.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* slow but accurate integer algorithm */
|
||||
JDCT_ISLOW,
|
||||
|
||||
/* faster, less accurate integer method */
|
||||
JDCT_IFAST,
|
||||
|
||||
/* floating-point: accurate, fast on fast HW */
|
||||
JDCT_FLOAT
|
||||
} J_DCT_METHOD;
|
||||
|
||||
/*
|
||||
Common fields between JPEG compression and decompression master structs.
|
||||
*/
|
||||
|
||||
#define jpeg_common_fields \
|
||||
/* Error handler module */ \
|
||||
struct jpeg_error_mgr *err; \
|
||||
/* Memory manager module */ \
|
||||
struct jpeg_memory_mgr *mem; \
|
||||
/* Progress monitor, or (void*)0 if none */ \
|
||||
struct jpeg_progress_mgr *progress; \
|
||||
/* Available for use by application */ \
|
||||
void *client_data; \
|
||||
/* So common code can tell which is which */ \
|
||||
int is_decompressor; \
|
||||
/* For checking call sequence validity */ \
|
||||
int global_state
|
||||
|
||||
/*
|
||||
Routines that are to be used by both halves of the library are declared to
|
||||
receive a pointer to this structure. There are no actual instances of
|
||||
jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
|
||||
*/
|
||||
|
||||
struct jpeg_common_struct {
|
||||
/* Fields common to both master struct types */
|
||||
jpeg_common_fields;
|
||||
|
||||
/*
|
||||
Additional fields follow in an actual jpeg_compress_struct or
|
||||
jpeg_decompress_struct. All three structs must agree on these initial
|
||||
fields! (This would be a lot cleaner in C++.)
|
||||
*/
|
||||
};
|
||||
|
||||
typedef struct jpeg_common_struct *j_common_ptr;
|
||||
typedef struct jpeg_compress_struct *j_compress_ptr;
|
||||
typedef struct jpeg_decompress_struct *j_decompress_ptr;
|
||||
|
||||
/*
|
||||
Master record for a compression instance
|
||||
*/
|
||||
|
||||
struct jpeg_compress_struct {
|
||||
/* Fields shared with jpeg_decompress_struct */
|
||||
jpeg_common_fields;
|
||||
|
||||
/* Destination for compressed data */
|
||||
struct jpeg_destination_mgr *dest;
|
||||
|
||||
/*
|
||||
Description of source image --- these fields must be filled in by outer
|
||||
application before starting compression. in_color_space must be correct
|
||||
before you can even call jpeg_set_defaults().
|
||||
*/
|
||||
|
||||
/* input image width */
|
||||
unsigned int image_width;
|
||||
|
||||
/* input image height */
|
||||
unsigned int image_height;
|
||||
|
||||
/* # of color components in input image */
|
||||
int input_components;
|
||||
|
||||
/* colorspace of input image */
|
||||
J_COLOR_SPACE in_color_space;
|
||||
|
||||
/* image gamma of input image */
|
||||
double input_gamma;
|
||||
|
||||
/*
|
||||
Compression parameters --- these fields must be set before calling
|
||||
jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
|
||||
initialize everything to reasonable defaults, then changing anything the
|
||||
application specifically wants to change. That way you won't get burnt
|
||||
when new parameters are added. Also note that there are several helper
|
||||
routines to simplify changing parameters.
|
||||
*/
|
||||
|
||||
/* bits of precision in image data */
|
||||
int data_precision;
|
||||
|
||||
/* # of color components in JPEG image */
|
||||
int num_components;
|
||||
|
||||
/* colorspace of JPEG image */
|
||||
J_COLOR_SPACE jpeg_color_space;
|
||||
|
||||
/* comp_info[i] describes component that appears i'th in SOF */
|
||||
jpeg_component_info *comp_info;
|
||||
|
||||
/* ptrs to coefficient quantization tables, or (void*)0 if not defined */
|
||||
JQUANT_TBL *quant_tbl_ptrs[4];
|
||||
|
||||
/* ptrs to Huffman coding tables, or (void*)0 if not defined */
|
||||
JHUFF_TBL *dc_huff_tbl_ptrs[4];
|
||||
JHUFF_TBL *ac_huff_tbl_ptrs[4];
|
||||
|
||||
/* L values for DC arith-coding tables */
|
||||
unsigned char arith_dc_L[16];
|
||||
|
||||
/* U values for DC arith-coding tables */
|
||||
unsigned char arith_dc_U[16];
|
||||
|
||||
/* Kx values for AC arith-coding tables */
|
||||
unsigned char arith_ac_K[16];
|
||||
|
||||
/* # of entries in scan_info array */
|
||||
int num_scans;
|
||||
|
||||
/*
|
||||
script for multi-scan file, or (void*)0
|
||||
The default value of scan_info is (void*)0, which causes a single-scan
|
||||
sequential JPEG file to be emitted. To create a multi-scan file, set
|
||||
num_scans and scan_info to point to an array of scan definitions.
|
||||
*/
|
||||
const jpeg_scan_info *scan_info;
|
||||
|
||||
/* 1=caller supplies downsampled data */
|
||||
int raw_data_in;
|
||||
|
||||
/* 1=arithmetic coding, 0=Huffman */
|
||||
int arith_code;
|
||||
|
||||
/* 1=optimize entropy encoding parms */
|
||||
int optimize_coding;
|
||||
|
||||
/* 1=first samples are cosited */
|
||||
int CCIR601_sampling;
|
||||
|
||||
/* 1..100, or 0 for no input smoothing */
|
||||
int smoothing_factor;
|
||||
|
||||
/* DCT algorithm selector */
|
||||
J_DCT_METHOD dct_method;
|
||||
|
||||
/*
|
||||
The restart interval can be specified in absolute MCUs by setting
|
||||
restart_interval, or in MCU rows by setting restart_in_rows (in which case
|
||||
the correct restart_interval will be figured for each scan).
|
||||
*/
|
||||
|
||||
/* MCUs per restart, or 0 for no restart */
|
||||
unsigned int restart_interval;
|
||||
|
||||
/* if > 0, MCU rows per restart interval */
|
||||
int restart_in_rows;
|
||||
|
||||
/*
|
||||
Parameters controlling emission of special markers.
|
||||
*/
|
||||
|
||||
/* should a JFIF marker be written? */
|
||||
int write_JFIF_header;
|
||||
|
||||
/* What to write for the JFIF version number */
|
||||
unsigned char JFIF_major_version;
|
||||
unsigned char JFIF_minor_version;
|
||||
|
||||
/*
|
||||
These three values are not used by the JPEG code, merely copied into the
|
||||
JFIF APP0 marker. density_unit can be 0 for unknown, 1 for dots/inch, or
|
||||
2 for dots/cm. Note that the pixel aspect ratio is defined by
|
||||
X_density/Y_density even when density_unit=0.
|
||||
*/
|
||||
|
||||
/* JFIF code for pixel size units */
|
||||
unsigned char density_unit;
|
||||
|
||||
/* Horizontal pixel density */
|
||||
unsigned short X_density;
|
||||
|
||||
/* Vertical pixel density */
|
||||
unsigned short Y_density;
|
||||
|
||||
/* should an Adobe marker be written? */
|
||||
int write_Adobe_marker;
|
||||
|
||||
/*
|
||||
State variable: index of next scanline to be written to
|
||||
jpeg_write_scanlines(). Application may use this to control its processing
|
||||
loop, e.g., "while (next_scanline < image_height)".
|
||||
*/
|
||||
|
||||
/* 0 .. image_height-1 */
|
||||
unsigned int next_scanline;
|
||||
|
||||
/*
|
||||
Remaining fields are known throughout compressor, but generally should not
|
||||
be touched by a surrounding application.
|
||||
*/
|
||||
|
||||
/*
|
||||
These fields are computed during compression startup
|
||||
*/
|
||||
|
||||
/* 1 if scan script uses progressive mode */
|
||||
int progressive_mode;
|
||||
|
||||
/* largest h_samp_factor */
|
||||
int max_h_samp_factor;
|
||||
|
||||
/* largest v_samp_factor */
|
||||
int max_v_samp_factor;
|
||||
|
||||
/*
|
||||
# of iMCU rows to be input to coef ctlr
|
||||
The coefficient controller receives data in units of MCU rows as defined
|
||||
for fully interleaved scans (whether the JPEG file is interleaved or not).
|
||||
There are v_samp_factor * DCTSIZE sample rows of each component in an
|
||||
"iMCU" (interleaved MCU) row.
|
||||
*/
|
||||
unsigned int total_iMCU_rows;
|
||||
|
||||
/*
|
||||
These fields are valid during any one scan. They describe the components
|
||||
and MCUs actually appearing in the scan.
|
||||
*/
|
||||
|
||||
/* # of JPEG components in this scan */
|
||||
int comps_in_scan;
|
||||
|
||||
/* *cur_comp_info[i] describes component that appears i'th in SOS */
|
||||
jpeg_component_info *cur_comp_info[4];
|
||||
|
||||
/* # of MCUs across the image */
|
||||
unsigned int MCUs_per_row;
|
||||
|
||||
/* # of MCU rows in the image */
|
||||
unsigned int MCU_rows_in_scan;
|
||||
|
||||
/* # of DCT blocks per MCU */
|
||||
int blocks_in_MCU;
|
||||
|
||||
/*
|
||||
MCU_membership[i] is index in cur_comp_info of component owning i'th block
|
||||
in an MCU
|
||||
*/
|
||||
int MCU_membership[10];
|
||||
|
||||
/* progressive JPEG parameters for scan */
|
||||
int Ss, Se, Ah, Al;
|
||||
|
||||
/*
|
||||
Links to compression subobjects (methods and private variables of
|
||||
modules)
|
||||
*/
|
||||
|
||||
struct jpeg_comp_master *master;
|
||||
struct jpeg_c_main_controller *main;
|
||||
struct jpeg_c_prep_controller *prep;
|
||||
struct jpeg_c_coef_controller *coef;
|
||||
struct jpeg_marker_writer *marker;
|
||||
struct jpeg_color_converter *cconvert;
|
||||
struct jpeg_downsampler *downsample;
|
||||
struct jpeg_forward_dct *fdct;
|
||||
struct jpeg_entropy_encoder *entropy;
|
||||
|
||||
/* workspace for jpeg_simple_progression */
|
||||
jpeg_scan_info *script_space;
|
||||
|
||||
int script_space_size;
|
||||
};
|
||||
|
||||
/*
|
||||
"Object" declarations for JPEG modules that may be supplied or called directly
|
||||
by the surrounding application. As with all objects in the JPEG library, these
|
||||
structs only define the publicly visible methods and state variables of a
|
||||
module. Additional private fields may exist after the public ones.
|
||||
*/
|
||||
|
||||
/*
|
||||
Error handler object
|
||||
*/
|
||||
|
||||
struct jpeg_error_mgr {
|
||||
/* Error exit handler: does not return to caller */
|
||||
void (*error_exit)(j_common_ptr cinfo);
|
||||
|
||||
/* Conditionally emit a trace or warning message */
|
||||
void (*emit_message)(j_common_ptr cinfo, int msg_level);
|
||||
|
||||
/* Routine that actually outputs a trace or error message */
|
||||
void (*output_message)(j_common_ptr cinfo);
|
||||
|
||||
/* Format a message string for the most recent JPEG error or message */
|
||||
void (*format_message)(j_common_ptr cinfo, char *buffer);
|
||||
|
||||
/* Reset error state variables at start of a new image */
|
||||
void (*reset_error_mgr)(j_common_ptr cinfo);
|
||||
|
||||
/*
|
||||
The message ID code and any parameters are saved here. A message can have
|
||||
one string parameter or up to 8 int parameters.
|
||||
*/
|
||||
int msg_code;
|
||||
|
||||
union {
|
||||
int i[8];
|
||||
char s[80];
|
||||
} msg_parm;
|
||||
|
||||
/*
|
||||
Standard state variables for error facility
|
||||
*/
|
||||
|
||||
/* max msg_level that will be displayed */
|
||||
int trace_level;
|
||||
|
||||
/*
|
||||
For recoverable corrupt-data errors, we emit a warning message, but keep
|
||||
going unless emit_message chooses to abort. emit_message should count
|
||||
warnings in num_warnings. The surrounding application can check for bad
|
||||
data by seeing if num_warnings is nonzero at the end of processing.
|
||||
*/
|
||||
|
||||
/* number of corrupt-data warnings */
|
||||
long num_warnings;
|
||||
|
||||
/*
|
||||
These fields point to the table(s) of error message strings. An
|
||||
application can change the table pointer to switch to a different message
|
||||
list (typically, to change the language in which errors are reported).
|
||||
Some applications may wish to add additional error codes that will be
|
||||
handled by the JPEG library error mechanism; the second table pointer is
|
||||
used for this purpose.
|
||||
|
||||
First table includes all errors generated by JPEG library itself. Error
|
||||
code 0 is reserved for a "no such error string" message.
|
||||
*/
|
||||
|
||||
/* Library errors */
|
||||
const char *const *jpeg_message_table;
|
||||
|
||||
/* Table contains strings 0..last_jpeg_message */
|
||||
int last_jpeg_message;
|
||||
|
||||
/*
|
||||
Second table can be added by application (see cjpeg/djpeg for example). It
|
||||
contains strings numbered first_addon_message..last_addon_message.
|
||||
*/
|
||||
|
||||
/* Non-library errors */
|
||||
const char *const *addon_message_table;
|
||||
|
||||
/* code for first string in addon table */
|
||||
int first_addon_message;
|
||||
|
||||
/* code for last string in addon table */
|
||||
int last_addon_message;
|
||||
};
|
||||
|
||||
/*
|
||||
Progress monitor object
|
||||
*/
|
||||
|
||||
struct jpeg_progress_mgr {
|
||||
void (*progress_monitor)(j_common_ptr cinfo);
|
||||
|
||||
/* work units completed in this pass */
|
||||
long pass_counter;
|
||||
|
||||
/* total number of work units in this pass */
|
||||
long pass_limit;
|
||||
|
||||
/* passes completed so far */
|
||||
int completed_passes;
|
||||
|
||||
/* total number of passes expected */
|
||||
int total_passes;
|
||||
};
|
||||
|
||||
/*
|
||||
Data destination object for compression
|
||||
*/
|
||||
|
||||
struct jpeg_destination_mgr {
|
||||
/* => next byte to write in buffer */
|
||||
unsigned char *next_output_byte;
|
||||
|
||||
/* # of byte spaces remaining in buffer */
|
||||
long unsigned int free_in_buffer;
|
||||
|
||||
void (*init_destination)(j_compress_ptr cinfo);
|
||||
int (*empty_output_buffer)(j_compress_ptr cinfo);
|
||||
void (*term_destination)(j_compress_ptr cinfo);
|
||||
};
|
||||
|
||||
/*
|
||||
Memory manager object.
|
||||
Allocates "small" objects (a few K total), "large" objects (tens of K), and
|
||||
"really big" objects (virtual arrays with backing store if needed). The memory
|
||||
manager does not allow individual objects to be freed; rather, each created
|
||||
object is assigned to a pool, and whole pools can be freed at once. This is
|
||||
faster and more convenient than remembering exactly what to free, especially
|
||||
where malloc()/free() are not too speedy.
|
||||
NB: alloc routines never return (void*)0. They exit to error_exit if not
|
||||
successful.
|
||||
*/
|
||||
|
||||
typedef struct jvirt_sarray_control *jvirt_sarray_ptr;
|
||||
typedef struct jvirt_barray_control *jvirt_barray_ptr;
|
||||
|
||||
struct jpeg_memory_mgr {
|
||||
/*
|
||||
Method pointers
|
||||
*/
|
||||
void *(*alloc_small)(j_common_ptr cinfo, int pool_id,
|
||||
long unsigned int sizeofobject);
|
||||
|
||||
void *(*alloc_large)(j_common_ptr cinfo, int pool_id,
|
||||
long unsigned int sizeofobject);
|
||||
|
||||
JSAMPARRAY (*alloc_sarray)(j_common_ptr cinfo, int pool_id,
|
||||
unsigned int samplesperrow,
|
||||
unsigned int numrows);
|
||||
|
||||
JBLOCKARRAY (*alloc_barray)(j_common_ptr cinfo, int pool_id,
|
||||
unsigned int blocksperrow,
|
||||
unsigned int numrows);
|
||||
|
||||
jvirt_sarray_ptr (*request_virt_sarray)(j_common_ptr cinfo, int pool_id,
|
||||
int pre_zero,
|
||||
unsigned int samplesperrow,
|
||||
unsigned int numrows,
|
||||
unsigned int maxaccess);
|
||||
|
||||
jvirt_barray_ptr (*request_virt_barray)(j_common_ptr cinfo, int pool_id,
|
||||
int pre_zero,
|
||||
unsigned int blocksperrow,
|
||||
unsigned int numrows,
|
||||
unsigned int maxaccess);
|
||||
|
||||
void (*realize_virt_arrays)(j_common_ptr cinfo);
|
||||
|
||||
JSAMPARRAY (*access_virt_sarray)(j_common_ptr cinfo, jvirt_sarray_ptr ptr,
|
||||
unsigned int start_row,
|
||||
unsigned int num_rows, int writable);
|
||||
|
||||
JBLOCKARRAY (*access_virt_barray)(j_common_ptr cinfo, jvirt_barray_ptr ptr,
|
||||
unsigned int start_row,
|
||||
unsigned int num_rows, int writable);
|
||||
|
||||
void (*free_pool)(j_common_ptr cinfo, int pool_id);
|
||||
|
||||
void (*self_destruct)(j_common_ptr cinfo);
|
||||
|
||||
/*
|
||||
Limit on memory allocation for this JPEG object. (Note that this is merely
|
||||
advisory, not a guaranteed maximum; it only affects the space used for
|
||||
virtual-array buffers.) May be changed by outer application after creating
|
||||
the JPEG object.
|
||||
*/
|
||||
long max_memory_to_use;
|
||||
|
||||
/* Maximum allocation request accepted by alloc_large. */
|
||||
long max_alloc_chunk;
|
||||
};
|
||||
|
||||
#endif /* JPEGLIB_H */
|
||||
757
targets/wasm-tacle/sequential/cjpeg_transupp/jpeglib.h
Executable file
757
targets/wasm-tacle/sequential/cjpeg_transupp/jpeglib.h
Executable file
@ -0,0 +1,757 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: jpeglib
|
||||
|
||||
Author: Thomas G. Lane
|
||||
|
||||
Function: This file defines the application interface for the JPEG library.
|
||||
Most applications using the library need only include this file, and perhaps
|
||||
jerror.h if they want to know the exact error codes.
|
||||
|
||||
Source: MediaBench II
|
||||
http://euler.slu.edu/~fritts/mediabench (mirror)
|
||||
|
||||
Original name: cjpeg
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the accompanying README file.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef JPEGLIB_H
|
||||
#define JPEGLIB_H
|
||||
|
||||
/*
|
||||
Various constants determining the sizes of things.
|
||||
All of these are specified by the JPEG standard, so don't change them if you
|
||||
want to be compatible.
|
||||
*/
|
||||
|
||||
/* The basic DCT block is 8x8 samples */
|
||||
#define DCTSIZE 8
|
||||
|
||||
/* DCTSIZE squared; # of elements in a block */
|
||||
#define DCTSIZE2 64
|
||||
|
||||
|
||||
/*
|
||||
Data structures for images (arrays of samples and of DCT coefficients).
|
||||
On 80x86 machines, the image arrays are too big for near pointers, but the
|
||||
pointer arrays can fit in near memory.
|
||||
*/
|
||||
|
||||
/* ptr to one image row of pixel samples. */
|
||||
typedef unsigned char *JSAMPROW;
|
||||
|
||||
/* ptr to some rows (a 2-D sample array) */
|
||||
typedef JSAMPROW *JSAMPARRAY;
|
||||
|
||||
/* one block of coefficients */
|
||||
typedef signed char JBLOCK[DCTSIZE2];
|
||||
|
||||
/* pointer to one row of coefficient blocks */
|
||||
typedef JBLOCK *JBLOCKROW;
|
||||
|
||||
/* a 2-D array of coefficient blocks */
|
||||
typedef JBLOCKROW *JBLOCKARRAY;
|
||||
|
||||
/* useful in a couple of places */
|
||||
typedef signed char *JCOEFPTR;
|
||||
|
||||
|
||||
/*
|
||||
DCT coefficient quantization tables.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* quantization step for each coefficient */
|
||||
/*
|
||||
This array gives the coefficient quantizers in natural array order (not the
|
||||
zigzag order in which they are stored in a JPEG DQT marker).
|
||||
CAUTION: IJG versions prior to v6a kept this array in zigzag order.
|
||||
*/
|
||||
unsigned short quantval[ DCTSIZE2 ];
|
||||
|
||||
/* 1 when table has been output */
|
||||
/*
|
||||
This field is used only during compression. It's initialized 0 when the
|
||||
table is created, and set 1 when it's been output to the file. You could
|
||||
suppress output of a table by setting this to 1. (See jpeg_suppress_tables
|
||||
for an example.)
|
||||
*/
|
||||
int sent_table;
|
||||
} JQUANT_TBL;
|
||||
|
||||
|
||||
/*
|
||||
Huffman coding tables.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* These two fields directly represent the contents of a JPEG DHT marker */
|
||||
|
||||
/* bits[k] = # of symbols with codes of */
|
||||
/* length k bits; bits[0] is unused */
|
||||
unsigned char bits[ 17 ];
|
||||
|
||||
/* The symbols, in order of incr code length */
|
||||
/*
|
||||
This field is used only during compression. It's initialized 0 when the
|
||||
table is created, and set 1 when it's been output to the file. You could
|
||||
suppress output of a table by setting this to 1. (See jpeg_suppress_tables
|
||||
for an example.)
|
||||
*/
|
||||
unsigned char huffval[ 256 ];
|
||||
|
||||
/* 1 when table has been output */
|
||||
int sent_table;
|
||||
} JHUFF_TBL;
|
||||
|
||||
|
||||
/*
|
||||
Basic info about one component (color channel).
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
These values are fixed over the whole image. For compression, they must be
|
||||
supplied by parameter setup; for decompression, they are read from the SOF
|
||||
marker.
|
||||
*/
|
||||
|
||||
/* identifier for this component (0..255) */
|
||||
int component_id;
|
||||
|
||||
/* its index in SOF or cinfo->comp_info[] */
|
||||
int component_index;
|
||||
|
||||
/* horizontal sampling factor (1..4) */
|
||||
int h_samp_factor;
|
||||
|
||||
/* vertical sampling factor (1..4) */
|
||||
int v_samp_factor;
|
||||
|
||||
/* quantization table selector (0..3) */
|
||||
int quant_tbl_no;
|
||||
|
||||
/*
|
||||
These values may vary between scans. For compression, they must be supplied
|
||||
by parameter setup; for decompression, they are read from the SOS marker.
|
||||
The decompressor output side may not use these variables.
|
||||
*/
|
||||
|
||||
/* DC entropy table selector (0..3) */
|
||||
int dc_tbl_no;
|
||||
|
||||
/* AC entropy table selector (0..3) */
|
||||
int ac_tbl_no;
|
||||
|
||||
/* Remaining fields should be treated as private by applications. */
|
||||
|
||||
/*
|
||||
These values are computed during compression or decompression startup:
|
||||
Component's size in DCT blocks. Any dummy blocks added to complete an MCU
|
||||
are not counted; therefore these values do not depend on whether a scan is
|
||||
interleaved or not.
|
||||
*/
|
||||
unsigned int width_in_blocks;
|
||||
unsigned int height_in_blocks;
|
||||
|
||||
/*
|
||||
Size of a DCT block in samples. Always DCTSIZE for compression. For
|
||||
decompression this is the size of the output from one DCT block, reflecting
|
||||
any scaling we choose to apply during the IDCT step. Values of 1,2,4,8 are
|
||||
likely to be supported. Note that different components may receive different
|
||||
IDCT scalings.
|
||||
*/
|
||||
int DCT_scaled_size;
|
||||
|
||||
/*
|
||||
The downsampled dimensions are the component's actual, unpadded number of
|
||||
samples at the main buffer (preprocessing/compression interface), thus
|
||||
downsampled_width = ceil(image_width * Hi/Hmax) and similarly for height.
|
||||
For decompression, IDCT scaling is included, so
|
||||
downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
|
||||
*/
|
||||
|
||||
/* actual width in samples */
|
||||
unsigned int downsampled_width;
|
||||
|
||||
/* actual height in samples */
|
||||
unsigned int downsampled_height;
|
||||
|
||||
/*
|
||||
This flag is used only for decompression. In cases where some of the
|
||||
components will be ignored (eg grayscale output from YCbCr image), we can
|
||||
skip most computations for the unused components.
|
||||
*/
|
||||
|
||||
/* do we need the value of this component? */
|
||||
int component_needed;
|
||||
|
||||
/*
|
||||
These values are computed before starting a scan of the component. The
|
||||
decompressor output side may not use these variables.
|
||||
*/
|
||||
|
||||
/* number of blocks per MCU, horizontally */
|
||||
int MCU_width;
|
||||
|
||||
/* number of blocks per MCU, vertically */
|
||||
int MCU_height;
|
||||
|
||||
/* MCU_width * MCU_height */
|
||||
int MCU_blocks;
|
||||
|
||||
/* MCU width in samples, MCU_width*DCT_scaled_size */
|
||||
int MCU_sample_width;
|
||||
|
||||
/* # of non-dummy blocks across in last MCU */
|
||||
int last_col_width;
|
||||
|
||||
/* # of non-dummy blocks down in last MCU */
|
||||
int last_row_height;
|
||||
|
||||
/*
|
||||
Saved quantization table for component; (void*)0 if none yet saved. See
|
||||
jdinput.c comments about the need for this information. This field is
|
||||
currently used only for decompression.
|
||||
*/
|
||||
JQUANT_TBL *quant_table;
|
||||
|
||||
/* Private per-component storage for DCT or IDCT subsystem. */
|
||||
void *dct_table;
|
||||
} jpeg_component_info;
|
||||
|
||||
|
||||
/*
|
||||
The script for encoding a multiple-scan file is an array of these:
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* number of components encoded in this scan */
|
||||
int comps_in_scan;
|
||||
|
||||
/* their SOF/comp_info[] indexes */
|
||||
int component_index[ 4 ];
|
||||
|
||||
/* progressive JPEG spectral selection parms */
|
||||
int Ss, Se;
|
||||
|
||||
/* progressive JPEG successive approx. parms */
|
||||
int Ah, Al;
|
||||
} jpeg_scan_info;
|
||||
|
||||
|
||||
/*
|
||||
Known color spaces.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* error/unspecified */
|
||||
JCS_UNKNOWN,
|
||||
|
||||
/* monochrome */
|
||||
JCS_GRAYSCALE,
|
||||
|
||||
/* red/green/blue */
|
||||
JCS_RGB,
|
||||
|
||||
/* Y/Cb/Cr (also known as YUV) */
|
||||
JCS_YCbCr,
|
||||
|
||||
/* C/M/Y/K */
|
||||
JCS_CMYK,
|
||||
|
||||
/* Y/Cb/Cr/K */
|
||||
JCS_YCCK
|
||||
} J_COLOR_SPACE;
|
||||
|
||||
|
||||
/*
|
||||
DCT/IDCT algorithm options.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* slow but accurate integer algorithm */
|
||||
JDCT_ISLOW,
|
||||
|
||||
/* faster, less accurate integer method */
|
||||
JDCT_IFAST,
|
||||
|
||||
/* floating-point: accurate, fast on fast HW */
|
||||
JDCT_FLOAT
|
||||
} J_DCT_METHOD;
|
||||
|
||||
|
||||
/*
|
||||
Common fields between JPEG compression and decompression master structs.
|
||||
*/
|
||||
|
||||
#define jpeg_common_fields \
|
||||
/* Error handler module */\
|
||||
struct jpeg_error_mgr *err; \
|
||||
/* Memory manager module */\
|
||||
struct jpeg_memory_mgr *mem; \
|
||||
/* Progress monitor, or (void*)0 if none */\
|
||||
struct jpeg_progress_mgr *progress; \
|
||||
/* Available for use by application */\
|
||||
void *client_data; \
|
||||
/* So common code can tell which is which */\
|
||||
int is_decompressor; \
|
||||
/* For checking call sequence validity */\
|
||||
int global_state
|
||||
|
||||
|
||||
/*
|
||||
Routines that are to be used by both halves of the library are declared to
|
||||
receive a pointer to this structure. There are no actual instances of
|
||||
jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
|
||||
*/
|
||||
|
||||
struct jpeg_common_struct {
|
||||
/* Fields common to both master struct types */
|
||||
jpeg_common_fields;
|
||||
|
||||
/*
|
||||
Additional fields follow in an actual jpeg_compress_struct or
|
||||
jpeg_decompress_struct. All three structs must agree on these initial
|
||||
fields! (This would be a lot cleaner in C++.)
|
||||
*/
|
||||
};
|
||||
|
||||
typedef struct jpeg_common_struct *j_common_ptr;
|
||||
typedef struct jpeg_compress_struct *j_compress_ptr;
|
||||
typedef struct jpeg_decompress_struct *j_decompress_ptr;
|
||||
|
||||
|
||||
/*
|
||||
Master record for a compression instance
|
||||
*/
|
||||
|
||||
struct jpeg_compress_struct {
|
||||
/* Fields shared with jpeg_decompress_struct */
|
||||
jpeg_common_fields;
|
||||
|
||||
/* Destination for compressed data */
|
||||
struct jpeg_destination_mgr *dest;
|
||||
|
||||
/*
|
||||
Description of source image --- these fields must be filled in by outer
|
||||
application before starting compression. in_color_space must be correct
|
||||
before you can even call jpeg_set_defaults().
|
||||
*/
|
||||
|
||||
/* input image width */
|
||||
unsigned int image_width;
|
||||
|
||||
/* input image height */
|
||||
unsigned int image_height;
|
||||
|
||||
/* # of color components in input image */
|
||||
int input_components;
|
||||
|
||||
/* colorspace of input image */
|
||||
J_COLOR_SPACE in_color_space;
|
||||
|
||||
/* image gamma of input image */
|
||||
double input_gamma;
|
||||
|
||||
/*
|
||||
Compression parameters --- these fields must be set before calling
|
||||
jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
|
||||
initialize everything to reasonable defaults, then changing anything the
|
||||
application specifically wants to change. That way you won't get burnt when
|
||||
new parameters are added. Also note that there are several helper routines
|
||||
to simplify changing parameters.
|
||||
*/
|
||||
|
||||
/* bits of precision in image data */
|
||||
int data_precision;
|
||||
|
||||
/* # of color components in JPEG image */
|
||||
int num_components;
|
||||
|
||||
/* colorspace of JPEG image */
|
||||
J_COLOR_SPACE jpeg_color_space;
|
||||
|
||||
/* comp_info[i] describes component that appears i'th in SOF */
|
||||
jpeg_component_info *comp_info;
|
||||
|
||||
/* ptrs to coefficient quantization tables, or (void*)0 if not defined */
|
||||
JQUANT_TBL *quant_tbl_ptrs[ 4 ];
|
||||
|
||||
/* ptrs to Huffman coding tables, or (void*)0 if not defined */
|
||||
JHUFF_TBL *dc_huff_tbl_ptrs[ 4 ];
|
||||
JHUFF_TBL *ac_huff_tbl_ptrs[ 4 ];
|
||||
|
||||
/* L values for DC arith-coding tables */
|
||||
unsigned char arith_dc_L[ 16 ];
|
||||
|
||||
/* U values for DC arith-coding tables */
|
||||
unsigned char arith_dc_U[ 16 ];
|
||||
|
||||
/* Kx values for AC arith-coding tables */
|
||||
unsigned char arith_ac_K[ 16 ];
|
||||
|
||||
/* # of entries in scan_info array */
|
||||
int num_scans;
|
||||
|
||||
/*
|
||||
script for multi-scan file, or (void*)0
|
||||
The default value of scan_info is (void*)0, which causes a single-scan
|
||||
sequential JPEG file to be emitted. To create a multi-scan file, set
|
||||
num_scans and scan_info to point to an array of scan definitions.
|
||||
*/
|
||||
const jpeg_scan_info *scan_info;
|
||||
|
||||
/* 1=caller supplies downsampled data */
|
||||
int raw_data_in;
|
||||
|
||||
/* 1=arithmetic coding, 0=Huffman */
|
||||
int arith_code;
|
||||
|
||||
/* 1=optimize entropy encoding parms */
|
||||
int optimize_coding;
|
||||
|
||||
/* 1=first samples are cosited */
|
||||
int CCIR601_sampling;
|
||||
|
||||
/* 1..100, or 0 for no input smoothing */
|
||||
int smoothing_factor;
|
||||
|
||||
/* DCT algorithm selector */
|
||||
J_DCT_METHOD dct_method;
|
||||
|
||||
|
||||
/*
|
||||
The restart interval can be specified in absolute MCUs by setting
|
||||
restart_interval, or in MCU rows by setting restart_in_rows (in which case
|
||||
the correct restart_interval will be figured for each scan).
|
||||
*/
|
||||
|
||||
/* MCUs per restart, or 0 for no restart */
|
||||
unsigned int restart_interval;
|
||||
|
||||
/* if > 0, MCU rows per restart interval */
|
||||
int restart_in_rows;
|
||||
|
||||
|
||||
/*
|
||||
Parameters controlling emission of special markers.
|
||||
*/
|
||||
|
||||
/* should a JFIF marker be written? */
|
||||
int write_JFIF_header;
|
||||
|
||||
/* What to write for the JFIF version number */
|
||||
unsigned char JFIF_major_version;
|
||||
unsigned char JFIF_minor_version;
|
||||
|
||||
/*
|
||||
These three values are not used by the JPEG code, merely copied into the
|
||||
JFIF APP0 marker. density_unit can be 0 for unknown, 1 for dots/inch, or 2
|
||||
for dots/cm. Note that the pixel aspect ratio is defined by
|
||||
X_density/Y_density even when density_unit=0.
|
||||
*/
|
||||
|
||||
/* JFIF code for pixel size units */
|
||||
unsigned char density_unit;
|
||||
|
||||
/* Horizontal pixel density */
|
||||
unsigned short X_density;
|
||||
|
||||
/* Vertical pixel density */
|
||||
unsigned short Y_density;
|
||||
|
||||
/* should an Adobe marker be written? */
|
||||
int write_Adobe_marker;
|
||||
|
||||
/*
|
||||
State variable: index of next scanline to be written to
|
||||
jpeg_write_scanlines(). Application may use this to control its processing
|
||||
loop, e.g., "while (next_scanline < image_height)".
|
||||
*/
|
||||
|
||||
/* 0 .. image_height-1 */
|
||||
unsigned int next_scanline;
|
||||
|
||||
|
||||
/*
|
||||
Remaining fields are known throughout compressor, but generally should not
|
||||
be touched by a surrounding application.
|
||||
*/
|
||||
|
||||
/*
|
||||
These fields are computed during compression startup
|
||||
*/
|
||||
|
||||
/* 1 if scan script uses progressive mode */
|
||||
int progressive_mode;
|
||||
|
||||
/* largest h_samp_factor */
|
||||
int max_h_samp_factor;
|
||||
|
||||
/* largest v_samp_factor */
|
||||
int max_v_samp_factor;
|
||||
|
||||
/*
|
||||
# of iMCU rows to be input to coef ctlr
|
||||
The coefficient controller receives data in units of MCU rows as defined for
|
||||
fully interleaved scans (whether the JPEG file is interleaved or not). There
|
||||
are v_samp_factor * DCTSIZE sample rows of each component in an "iMCU"
|
||||
(interleaved MCU) row.
|
||||
*/
|
||||
unsigned int total_iMCU_rows;
|
||||
|
||||
/*
|
||||
These fields are valid during any one scan. They describe the components
|
||||
and MCUs actually appearing in the scan.
|
||||
*/
|
||||
|
||||
/* # of JPEG components in this scan */
|
||||
int comps_in_scan;
|
||||
|
||||
/* *cur_comp_info[i] describes component that appears i'th in SOS */
|
||||
jpeg_component_info *cur_comp_info[ 4 ];
|
||||
|
||||
/* # of MCUs across the image */
|
||||
unsigned int MCUs_per_row;
|
||||
|
||||
/* # of MCU rows in the image */
|
||||
unsigned int MCU_rows_in_scan;
|
||||
|
||||
/* # of DCT blocks per MCU */
|
||||
int blocks_in_MCU;
|
||||
|
||||
/*
|
||||
MCU_membership[i] is index in cur_comp_info of component owning i'th block
|
||||
in an MCU
|
||||
*/
|
||||
int MCU_membership[ 10 ];
|
||||
|
||||
/* progressive JPEG parameters for scan */
|
||||
int Ss, Se, Ah, Al;
|
||||
|
||||
/*
|
||||
Links to compression subobjects (methods and private variables of modules)
|
||||
*/
|
||||
|
||||
struct jpeg_comp_master *master;
|
||||
struct jpeg_c_main_controller *main;
|
||||
struct jpeg_c_prep_controller *prep;
|
||||
struct jpeg_c_coef_controller *coef;
|
||||
struct jpeg_marker_writer *marker;
|
||||
struct jpeg_color_converter *cconvert;
|
||||
struct jpeg_downsampler *downsample;
|
||||
struct jpeg_forward_dct *fdct;
|
||||
struct jpeg_entropy_encoder *entropy;
|
||||
|
||||
/* workspace for jpeg_simple_progression */
|
||||
jpeg_scan_info *script_space;
|
||||
|
||||
int script_space_size;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
"Object" declarations for JPEG modules that may be supplied or called directly
|
||||
by the surrounding application. As with all objects in the JPEG library, these
|
||||
structs only define the publicly visible methods and state variables of a
|
||||
module. Additional private fields may exist after the public ones.
|
||||
*/
|
||||
|
||||
/*
|
||||
Error handler object
|
||||
*/
|
||||
|
||||
struct jpeg_error_mgr {
|
||||
/* Error exit handler: does not return to caller */
|
||||
void ( *error_exit ) ( j_common_ptr cinfo );
|
||||
|
||||
/* Conditionally emit a trace or warning message */
|
||||
void ( *emit_message ) ( j_common_ptr cinfo, int msg_level );
|
||||
|
||||
/* Routine that actually outputs a trace or error message */
|
||||
void ( *output_message ) ( j_common_ptr cinfo );
|
||||
|
||||
/* Format a message string for the most recent JPEG error or message */
|
||||
void ( *format_message ) ( j_common_ptr cinfo, char *buffer );
|
||||
|
||||
/* Reset error state variables at start of a new image */
|
||||
void ( *reset_error_mgr ) ( j_common_ptr cinfo );
|
||||
|
||||
/*
|
||||
The message ID code and any parameters are saved here. A message can have
|
||||
one string parameter or up to 8 int parameters.
|
||||
*/
|
||||
int msg_code;
|
||||
|
||||
union {
|
||||
int i[ 8 ];
|
||||
char s[ 80 ];
|
||||
} msg_parm;
|
||||
|
||||
|
||||
/*
|
||||
Standard state variables for error facility
|
||||
*/
|
||||
|
||||
/* max msg_level that will be displayed */
|
||||
int trace_level;
|
||||
|
||||
/*
|
||||
For recoverable corrupt-data errors, we emit a warning message, but keep
|
||||
going unless emit_message chooses to abort. emit_message should count
|
||||
warnings in num_warnings. The surrounding application can check for bad data
|
||||
by seeing if num_warnings is nonzero at the end of processing.
|
||||
*/
|
||||
|
||||
/* number of corrupt-data warnings */
|
||||
long num_warnings;
|
||||
|
||||
/*
|
||||
These fields point to the table(s) of error message strings. An application
|
||||
can change the table pointer to switch to a different message list
|
||||
(typically, to change the language in which errors are reported). Some
|
||||
applications may wish to add additional error codes that will be handled by
|
||||
the JPEG library error mechanism; the second table pointer is used for this
|
||||
purpose.
|
||||
|
||||
First table includes all errors generated by JPEG library itself. Error
|
||||
code 0 is reserved for a "no such error string" message.
|
||||
*/
|
||||
|
||||
/* Library errors */
|
||||
const char *const *jpeg_message_table;
|
||||
|
||||
/* Table contains strings 0..last_jpeg_message */
|
||||
int last_jpeg_message;
|
||||
|
||||
/*
|
||||
Second table can be added by application (see cjpeg/djpeg for example). It
|
||||
contains strings numbered first_addon_message..last_addon_message.
|
||||
*/
|
||||
|
||||
/* Non-library errors */
|
||||
const char *const *addon_message_table;
|
||||
|
||||
/* code for first string in addon table */
|
||||
int first_addon_message;
|
||||
|
||||
/* code for last string in addon table */
|
||||
int last_addon_message;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Progress monitor object
|
||||
*/
|
||||
|
||||
struct jpeg_progress_mgr {
|
||||
void ( *progress_monitor ) ( j_common_ptr cinfo );
|
||||
|
||||
/* work units completed in this pass */
|
||||
long pass_counter;
|
||||
|
||||
/* total number of work units in this pass */
|
||||
long pass_limit;
|
||||
|
||||
/* passes completed so far */
|
||||
int completed_passes;
|
||||
|
||||
/* total number of passes expected */
|
||||
int total_passes;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Data destination object for compression
|
||||
*/
|
||||
|
||||
struct jpeg_destination_mgr {
|
||||
/* => next byte to write in buffer */
|
||||
unsigned char *next_output_byte;
|
||||
|
||||
/* # of byte spaces remaining in buffer */
|
||||
long unsigned int free_in_buffer;
|
||||
|
||||
void ( *init_destination ) ( j_compress_ptr cinfo );
|
||||
int ( *empty_output_buffer ) ( j_compress_ptr cinfo );
|
||||
void ( *term_destination ) ( j_compress_ptr cinfo );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Memory manager object.
|
||||
Allocates "small" objects (a few K total), "large" objects (tens of K), and
|
||||
"really big" objects (virtual arrays with backing store if needed). The memory
|
||||
manager does not allow individual objects to be freed; rather, each created
|
||||
object is assigned to a pool, and whole pools can be freed at once. This is
|
||||
faster and more convenient than remembering exactly what to free, especially
|
||||
where malloc()/free() are not too speedy.
|
||||
NB: alloc routines never return (void*)0. They exit to error_exit if not
|
||||
successful.
|
||||
*/
|
||||
|
||||
typedef struct jvirt_sarray_control *jvirt_sarray_ptr;
|
||||
typedef struct jvirt_barray_control *jvirt_barray_ptr;
|
||||
|
||||
struct jpeg_memory_mgr {
|
||||
/*
|
||||
Method pointers
|
||||
*/
|
||||
void *( *alloc_small ) (
|
||||
j_common_ptr cinfo, int pool_id, long unsigned int sizeofobject );
|
||||
|
||||
void *( *alloc_large ) (
|
||||
j_common_ptr cinfo, int pool_id, long unsigned int sizeofobject );
|
||||
|
||||
JSAMPARRAY ( *alloc_sarray ) (
|
||||
j_common_ptr cinfo, int pool_id, unsigned int samplesperrow,
|
||||
unsigned int numrows );
|
||||
|
||||
JBLOCKARRAY ( *alloc_barray )(
|
||||
j_common_ptr cinfo, int pool_id, unsigned int blocksperrow,
|
||||
unsigned int numrows );
|
||||
|
||||
jvirt_sarray_ptr ( *request_virt_sarray ) (
|
||||
j_common_ptr cinfo, int pool_id, int pre_zero, unsigned int samplesperrow,
|
||||
unsigned int numrows, unsigned int maxaccess );
|
||||
|
||||
jvirt_barray_ptr ( *request_virt_barray ) (
|
||||
j_common_ptr cinfo, int pool_id, int pre_zero, unsigned int blocksperrow,
|
||||
unsigned int numrows, unsigned int maxaccess );
|
||||
|
||||
void ( *realize_virt_arrays ) ( j_common_ptr cinfo );
|
||||
|
||||
JSAMPARRAY ( *access_virt_sarray ) (
|
||||
j_common_ptr cinfo, jvirt_sarray_ptr ptr, unsigned int start_row,
|
||||
unsigned int num_rows, int writable );
|
||||
|
||||
JBLOCKARRAY ( *access_virt_barray ) (
|
||||
j_common_ptr cinfo, jvirt_barray_ptr ptr, unsigned int start_row,
|
||||
unsigned int num_rows, int writable );
|
||||
|
||||
void ( *free_pool ) ( j_common_ptr cinfo, int pool_id );
|
||||
|
||||
void ( *self_destruct ) ( j_common_ptr cinfo );
|
||||
|
||||
/*
|
||||
Limit on memory allocation for this JPEG object. (Note that this is merely
|
||||
advisory, not a guaranteed maximum; it only affects the space used for
|
||||
virtual-array buffers.) May be changed by outer application after creating
|
||||
the JPEG object.
|
||||
*/
|
||||
long max_memory_to_use;
|
||||
|
||||
/* Maximum allocation request accepted by alloc_large. */
|
||||
long max_alloc_chunk;
|
||||
};
|
||||
|
||||
#endif /* JPEGLIB_H */
|
||||
Reference in New Issue
Block a user