Packaging and Encoding of Common Image Formats in [Image_Codec] - Android Platform JPG

Keywords: encoding github codec network

Article directory

JPG Picture Format

JPG (Joint Photographic Experts Group) is a commonly used lossy compressed image format. The compression ratio can be chosen to balance the size of the file with the quality of the image. The compression ratio is usually 10:1. In fact, JPEG is JPEG/Exif, JPEG/JFIF and other generic terms, so Jpeg generally uses. jpg and. jpeg, though. jpe,. JFIF and. jif file suffixes. JPEG compression scheme can compress similar tones very well, but JPEG compression scheme can not deal with the strong difference of brightness or the pure color region very well.

Compression modes and steps

There are several compression modes for JPEG:

  • Sequential Encoding
    The image is processed from left to right and from top to bottom at one time.
  • Progressive Encoding
    When the time of image transmission is long, the image can be processed fractionally to transmit the image from blur to clarity (the effect is similar to GIF transmission on the network).
  • Lossless Encoding
  • Hierarchical Encoding
    The image is compressed at several resolutions, the purpose of which is to enable high-resolution images to be displayed on lower-resolution devices.

Compression steps:

  • Color conversion
    Because JPEG only supports YUV color mode data structure, but does not support RGB image data structure, it is necessary to convert color mode data before compressing color image. The conversion of each value can be calculated by the following conversion formula:
    Y=0.299R+0.587G+0.114B
    U=-0.169R-0.3313G+0.5B
    V=0.5R-0.4187G-0.0813B
    Where Y denotes brightness, U and V denote color.
    Data sampling is also required after the conversion is completed. Generally, the sampling ratio is 4:1:1 or 4:2:2. Since only one row is reserved for each two rows after the implementation of this work, the image data volume after sampling will be compressed to half of the original.

  • DCT transformation
    DCT (Discrete Cosine Transform) is a process of transforming image signal in frequency domain to separate high frequency and low frequency information. Then the high-frequency part of the image (i.e. image details) is compressed to achieve the purpose of compressing image data.
    Firstly, the image is divided into several 8*8 matrices. Then each matrix is transformed by DCT, and a frequency coefficient matrix is obtained, in which the frequency coefficients are floating point numbers.

  • Quantification
    Since the codebooks used in the later coding process are all integers, it is necessary to quantify the transformed frequency coefficients and convert them into integers.
    After data quantization, the data in the matrix are approximate values, which are different from the original image data. This difference is the main reason for image distortion after compression.
    In this process, the selection of quality factors is very important. If the value is too large, the compression ratio can be greatly improved, but the image quality is poor. On the contrary, the smaller the quality factor (minimum 1), the better the image reconstruction quality, but the lower the compression ratio. To this end, ISO has developed a set of standard quantization values for JPEG code implementers.

  • Code
    From the previous process, we can see that the image has not been further compressed until the color conversion is completed. DCT transformation and quantization can be said to be the preparation for the coding stage.
    There are two mechanisms for encoding: run length encoding of 0 value and Entropy Coding.
    In JPEG, the hovering sequence is used, that is, the elements in the matrix are arranged in the normal direction of the diagonal line of the matrix. The advantage of this method is that the elements with larger values near the upper left corner of the matrix are arranged at the front of the stroke, while the matrix elements arranged at the back of the stroke are basically zero values. Run length encoding is a very simple and commonly used encoding method, which will not be discussed here.
    Coding is actually a coding method based on statistical characteristics. HUFFMAN coding or arithmetic coding is allowed in JPEG.

JPG file structure

We convert the previous Png image into Jpeg image by software:

[JPG sample picture] (https://img-blog.csdn.net/20180403183607538? Watermark/2/text/aHR0cHM6Ly9ibG9nLmNzG4ubmV0L2YW9qaWFuZ2x1bw=/font/5a6L5L2T/fontsize/400/I0JBQFCMA=/dissolve/70)

The magnified effect:

(https://img-blog.csdn.net/20180403183658438? Watermark/2/text/aHR0cHM6Ly9ibG9nLmNzG4ubmV0L2YW9qaWZ2x1bw=/font/5a6L5L2T/fontsize/400/fill/I0JBQFCMA=/dissolve/70)

Look at the converted image, it is totally different. This is the result of lossy compression. The image has been distorted. We just want to explain the problem here.

Open jpg_4_2_32bit.jpg with secondary tools:

00000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0060  ......JFIF.....`
00000010: 0060 0000 ffdb 0043 0002 0101 0201 0102  .`.....C........
00000020: 0202 0202 0202 0203 0503 0303 0303 0604  ................
00000030: 0403 0507 0607 0707 0607 0708 090b 0908  ................
00000040: 080a 0807 070a 0d0a 0a0b 0c0c 0c0c 0709  ................
00000050: 0e0f 0d0c 0e0b 0c0c 0cff db00 4301 0202  ............C...
00000060: 0203 0303 0603 0306 0c08 0708 0c0c 0c0c  ................
00000070: 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c  ................
00000080: 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c  ................
00000090: 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c ffc0  ................
000000a0: 0011 0800 0200 0403 0122 0002 1101 0311  ........."......
000000b0: 01ff c400 1f00 0001 0501 0101 0101 0100  ................
000000c0: 0000 0000 0000 0001 0203 0405 0607 0809  ................
000000d0: 0a0b ffc4 00b5 1000 0201 0303 0204 0305  ................
000000e0: 0504 0400 0001 7d01 0203 0004 1105 1221  ......}........!
000000f0: 3141 0613 5161 0722 7114 3281 91a1 0823  1A..Qa."q.2....#
00000100: 42b1 c115 52d1 f024 3362 7282 090a 1617  B...R..$3br.....
00000110: 1819 1a25 2627 2829 2a34 3536 3738 393a  ...%&'()*456789:
00000120: 4344 4546 4748 494a 5354 5556 5758 595a  CDEFGHIJSTUVWXYZ
00000130: 6364 6566 6768 696a 7374 7576 7778 797a  cdefghijstuvwxyz
00000140: 8384 8586 8788 898a 9293 9495 9697 9899  ................
00000150: 9aa2 a3a4 a5a6 a7a8 a9aa b2b3 b4b5 b6b7  ................
00000160: b8b9 bac2 c3c4 c5c6 c7c8 c9ca d2d3 d4d5  ................
00000170: d6d7 d8d9 dae1 e2e3 e4e5 e6e7 e8e9 eaf1  ................
00000180: f2f3 f4f5 f6f7 f8f9 faff c400 1f01 0003  ................
00000190: 0101 0101 0101 0101 0100 0000 0000 0001  ................
000001a0: 0203 0405 0607 0809 0a0b ffc4 00b5 1100  ................
000001b0: 0201 0204 0403 0407 0504 0400 0102 7700  ..............w.
000001c0: 0102 0311 0405 2131 0612 4151 0761 7113  ......!1..AQ.aq.
000001d0: 2232 8108 1442 91a1 b1c1 0923 3352 f015  "2...B.....#3R..
000001e0: 6272 d10a 1624 34e1 25f1 1718 191a 2627  br...$4.%.....&'
000001f0: 2829 2a35 3637 3839 3a43 4445 4647 4849  ()*56789:CDEFGHI
00000200: 4a53 5455 5657 5859 5a63 6465 6667 6869  JSTUVWXYZcdefghi
00000210: 6a73 7475 7677 7879 7a82 8384 8586 8788  jstuvwxyz.......
00000220: 898a 9293 9495 9697 9899 9aa2 a3a4 a5a6  ................
00000230: a7a8 a9aa b2b3 b4b5 b6b7 b8b9 bac2 c3c4  ................
00000240: c5c6 c7c8 c9ca d2d3 d4d5 d6d7 d8d9 dae2  ................
00000250: e3e4 e5e6 e7e8 e9ea f2f3 f4f5 f6f7 f8f9  ................
00000260: faff da00 0c03 0100 0211 0311 003f 00f9  .............?..
00000270: 1ffe 0afd e28d 4ff6 66ff 0082 887c 4af0  ......O.f....|J.
00000280: 9fc3 7d46 fbe1 f785 6c75 3716 fa37 86a7  ..}F....lu7..7..
00000290: 7d27 4fb7 da4c 6bb2 0b72 91ae 1234 4185  }'O..Lk..r...4A.
000002a0: e151 4740 0514 515f a064 1ff2 2ac2 7fd7  .QG@..Q_.d..*...
000002b0: aa5f fa6e 27f1 ff00 8a5f f254 e2fd 63ff  ._.n'...._.T..c.
000002c0: 00a4 44ff d9                             ..D..

The storage format of the converted image is GFIF. JPEG files can be roughly divided into two parts:

  • Marking code
    It consists of two bytes. The first byte is a fixed value of 0XFF, which represents the beginning of a tag code. The different values of the second byte represent different meanings. It should be noted that consecutive multiple 0XFFs can be understood as a 0XFF and represent the beginning of a tag code. In addition, tag codes usually appear in the form of tag codes in documents. For example, the SOI tag code is 0XFFD8, that is, if 0XFFD8 appears in the JPEG file, it represents a SOI tag here.

  • compressed data
    After a complete two-byte tag code is the compressed data corresponding to the tag code, which records a number of information about the file.

Some typical tag codes and the meanings they represent are as follows:

  • SOI
00000000: ffd8 ---- ---- ---- ---- ---- ---- ----  ......JFIF.....
Marking code byte Payload Tag code name describe
SOI 0xFF 0xD8 none Start Of Image The image starts with a markup code of fixed value 0XFFD8, expressed in 2 bytes.
  • APP0
00000000: ---- ffe0 0010 4a46 4946 0001 0101 0060  ......JFIF.....`
00000010: 0060 0000 ---- ---- ---- ---- ---- ----  .`.....C........
Marking code byte Payload Tag code name describe
APP0 0XFFE0 Application 0 The application retains markup 0 with a fixed value of 0XFFE0, expressed in 2 bytes; the markup code then contains nine specific fields

APP0 includes eight fields:

Byte describe
ffe0 APP0 marker
0010 Data length: 2 bytes to represent the total length of the nine fields of (1) - 9, that is, the fields that do not contain markup code but contain this field
4a46 4946 00 Indicator: 5 bytes, fixed value 0X4A6494600, representing the string "JFIF0"
0101 Version number: 2 bytes, usually 0X0102, representing JFIF version number of 1.2; but it may also be other values, thus representing other version numbers.
01 Density units in the X and Y directions: 1 byte, only three values are available, 0: no units; 1: points per inch; 2: points per centimeter
0060 X-Direction Pixel Density: 2 Bytes, Range of Value Unknown
0060 Y-Direction Pixel Density: 2 Bytes, Range of Value Unknown
00 Number of vertical pixels in thumbnails: 1 byte, unknown range of values
00 Number of vertical pixels in thumbnails: 1 byte, unknown range of values

Thumbnail RGB bitmap: The length may be a multiple of 3, and a 24-bit RGB bitmap is saved; if there is no thumbnail bitmap (which is more common), the values of field (7) (8) are all 0.

  • APPn

App0 is also a special one in AppN

Marking code byte Payload Tag code name describe
APPn 0xFF, 0xEn variable size Application n The application retains the tag n(n=1 - 15), the tag code is 2 bytes, and the value is 0XFFE1 - 0XFFFF FF; it contains two fields:
(1) Data length, 2 bytes, representing the total length of (1) (2) two fields; that is, it does not contain markup code, but contains the field;
(2) Details: data length - 2 bytes, content is uncertain;
  • DQT
00000010: ---- ---- ffdb 0043 0002 0101 0201 0102  .`.....C........
00000020: 0202 0202 0202 0203 0503 0303 0303 0604  ................
00000030: 0403 0507 0607 0707 0607 0708 090b 0908  ................
00000040: 080a 0807 070a 0d0a 0a0b 0c0c 0c0c 0709  ................
00000050: 0e0f 0d0c 0e0b 0c0c 0cff db00 4301 0202  ............C...
00000060: 0203 0303 0603 0306 0c08 0708 0c0c 0c0c  ................
00000070: 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c  ................
00000080: 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c  ................
00000090: 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c 0c0c ----  ................
Marking code byte Payload Tag code name describe
DQT Define Quantization Table Define quantization table; Markup code is fixed value 0XFFDB; Contains 9 specific fields

Data length: 2 bytes, representing the length of data and the total length of multiple quantization table fields; that is, it does not contain markup code, but contains the field; Quantization table: data length - 2 bytes, including the following contents: precision and quantization table ID, 1 byte, high 4-bit precision, only two optional values, 0:8; The lower 4 bits represent the quantization table ID, the range table item, 64 * (precision value + 1) bytes, for example, the 8-bit precision quantization table, whose item length is 64 * (0 + 1) = 64 bytes;

In this tag section, the quantization table can be repeated, representing multiple quantization tables, but only four times at most; in this section, there are two ffdb s.

  • SOFO
00000090: ---- ---- ---- ---- ---- ---- ---- ffc0  ................
000000a0: 0011 0800 0200 0403 0122 0002 1101 0311  ........."......
000000b0: 01ff c400 1f00 0001 0501 0101 0101 0100  ................
Marking code byte Payload Tag code name describe
SOFO ffc0 variable size Start Of Frame The frame image starts with a markup code of fixed value 0XFFC0, which contains nine specific fields:
Byte describe
0011 Data length: 2 bytes, the total length of the field; that is, it does not contain markup code, but contains the field.
08 Accuracy: 1 byte, representing the number of bits per data sample; usually 8 bits
00 02 Image height: 2 bytes, representing the image height in pixels. If DNL is not supported, it must be greater than 0.
00 04 Image width: 2 bytes, representing the image width in pixels. If DNL is not supported, it must be greater than 0.
03 Number of color components: 1 byte. Since JPEG uses YCrCb color space, it is constant to 3.
0122 0002 1101 0311 01 Color Component Information: Number of color components * 3 bytes, usually 9 bytes, and the following information is represented accordingly:
(a) Color component ID: 1 byte;
(b) Horizontal/vertical sampling factor: 1 byte, 4 bits high for horizontal sampling factor and 4 bits low for vertical sampling factor;
(c) Quantization table: 1 byte, the quantization table ID used by the current component

In this marker segment, the color component information should be repeated three times, because there are three color components.

  • DHT
000000d0: ---- ffc4 00b5 1000 0201 0303 0204 0305  ................
000000e0: 0504 0400 0001 7d01 0203 0004 1105 1221  ......}........!
000000f0: 3141 0613 5161 0722 7114 3281 91a1 0823  1A..Qa."q.2....#
00000100: 42b1 c115 52d1 f024 3362 7282 090a 1617  B...R..$3br.....
00000110: 1819 1a25 2627 2829 2a34 3536 3738 393a  ...%&'()*456789:
00000120: 4344 4546 4748 494a 5354 5556 5758 595a  CDEFGHIJSTUVWXYZ
00000130: 6364 6566 6768 696a 7374 7576 7778 797a  cdefghijstuvwxyz
00000140: 8384 8586 8788 898a 9293 9495 9697 9899  ................
00000150: 9aa2 a3a4 a5a6 a7a8 a9aa b2b3 b4b5 b6b7  ................
00000160: b8b9 bac2 c3c4 c5c6 c7c8 c9ca d2d3 d4d5  ................
00000170: d6d7 d8d9 dae1 e2e3 e4e5 e6e7 e8e9 eaf1  ................
00000180: f2f3 f4f5 f6f7 f8f9 faff c400 1f01 0003  ................
00000190: 0101 0101 0101 0101 0100 0000 0000 0001  ................
000001a0: 0203 0405 0607 0809 0a0b ffc4 00b5 1100  ................
000001b0: 0201 0204 0403 0407 0504 0400 0102 7700  ..............w.
000001c0: 0102 0311 0405 2131 0612 4151 0761 7113  ......!1..AQ.aq.
000001d0: 2232 8108 1442 91a1 b1c1 0923 3352 f015  "2...B.....#3R..
000001e0: 6272 d10a 1624 34e1 25f1 1718 191a 2627  br...$4.%.....&'
000001f0: 2829 2a35 3637 3839 3a43 4445 4647 4849  ()*56789:CDEFGHI
00000200: 4a53 5455 5657 5859 5a63 6465 6667 6869  JSTUVWXYZcdefghi
00000210: 6a73 7475 7677 7879 7a82 8384 8586 8788  jstuvwxyz.......
00000220: 898a 9293 9495 9697 9899 9aa2 a3a4 a5a6  ................
00000230: a7a8 a9aa b2b3 b4b5 b6b7 b8b9 bac2 c3c4  ................
00000240: c5c6 c7c8 c9ca d2d3 d4d5 d6d7 d8d9 dae2  ................
00000250: e3e4 e5e6 e7e8 e9ea f2f3 f4f5 f6f7 f8f9  ................
00000260: fa-- ---- ---- ---- ---- ---- ---- ----  .............?..
Marking code byte Payload Tag code name describe
DHT ffc4 variable size Define Huffman Table Define the Huffman table with the tag code 0XFFC4, which contains two fields:
(1) Data length, 2 bytes, does not contain markup code, but contains the field;
(2) Huffman table, data length - 2 bytes

The Huffman table includes:
Including table ID and table type, 1 byte, high 4 bits represent table type, with only two values: 0, DC DC; 1, AC; low 4 bits, Huffman table ID; it should be noted that DC table and AC table are coded separately. Including the number of different digits, 16 bytes. Including the encoding content, the sum of the number of 16 different bits of code words (bytes)

Huffman tables can be repeated, usually four times.

  • DRI
Marking code byte Payload Tag code name describe
DRI 0xFF, 0xDD 4 bytes Define Restart Interval Define the interval of cumulative reset of differential coding, label code is fixed value 0XFFDD

Contains two specific fields:
Data length: 2 bytes, fixed value 0X0004, the total length of the field; that is, does not contain markup code, but contains the field;

In the unit of MCU block, the restart interval: 2 bytes, if the value is n, means that every n MCU block has an RSTn tag; the first tag is RST0, the second is RST1, and RST7 repeats from RST0; if there is no segment of this tag, or the interval value is 0, there is no restart interval and RST tag;

  • SOS
00000260: --ff da00 0c03 0100 0211 0311 003f 00f9  .............?..
00000270: 1ffe 0afd e28d 4ff6 66ff 0082 887c 4af0  ......O.f....|J.
00000280: 9fc3 7d46 fbe1 f785 6c75 3716 fa37 86a7  ..}F....lu7..7..
00000290: 7d27 4fb7 da4c 6bb2 0b72 91ae 1234 4185  }'O..Lk..r...4A.
000002a0: e151 4740 0514 515f a064 1ff2 2ac2 7fd7  .QG@..Q_.d..*...
000002b0: aa5f fa6e 27f1 ff00 8a5f f254 e2fd 63ff  ._.n'...._.T..c.
000002c0: 00a4 44-- --                             ..D..
Marking code byte Payload Tag code name describe
SOS FFDA variable Start Of Scan Scanning begins; the tag code is 0XFFDA, which contains two specific fields:
Byte describe
00 0c Data length, 2 bytes, representing the total length of the field
03 Number of color components: 1 byte, only 3 optional values, 1: grayscale image; 3: YCrCb or YIQ; 4: CMYK
0100 0211 0311 Color component information: including the following fields, color component ID: 1 byte; DC/AC coefficient table ID, 1 byte, high 4-bit Huffman table ID for DC component; low 4-bit Huffman table ID for AC component
003f 00 Compressed image data: spectrum selection start: 1 byte, fixed value 0X00; spectrum selection end: 1 byte, fixed value 0X3F; spectrum selection: 1 byte, fixed value 0X00
  • data block
00000260: ---- ---- ---- ---- ---- ---- ---- --f9  .............?..
00000270: 1ffe 0afd e28d 4ff6 66ff 0082 887c 4af0  ......O.f....|J.
00000280: 9fc3 7d46 fbe1 f785 6c75 3716 fa37 86a7  ..}F....lu7..7..
00000290: 7d27 4fb7 da4c 6bb2 0b72 91ae 1234 4185  }'O..Lk..r...4A.
000002a0: e151 4740 0514 515f a064 1ff2 2ac2 7fd7  .QG@..Q_.d..*...
000002b0: aa5f fa6e 27f1 ff00 8a5f f254 e2fd 63ff  ._.n'...._.T..c.
000002c0: 00a4 44-- --                             ..D..
  • EOI
000002c0: ---- --ff d9                             ..D..
Marking code byte Payload Tag code name describe
EOI ffd9 none End Of Image, Image End; Markup Code 0XFFD9

libjpeg Encoding and Decoding Jpeg Pictures

Jpeg can be coded and decoded by libjpeg-turbo, which is accelerated by SIMD and can improve the performance of coding and decoding. Android uses version 1.5.1. The latest version of the code can be downloaded on github:

https://github.com/libjpeg-turbo/libjpeg-turbo.git

Our sample code can also be downloaded on github: Codec-JPGCodec

When compiling libjpeg, it is necessary to compile SIMD according to the platform.

if(${ANDROID_ABI} STREQUAL "arm")
    MESSAGE(STATUS "JPEG: arm")
    set(JPEG_SOURCES
            jpeg/libjpeg-turbo/simd/jsimd_arm_neon.S
            jpeg/libjpeg-turbo/simd/jsimd_arm.c )
elseif(${ANDROID_ABI} STREQUAL "arm64")
    MESSAGE(STATUS "JPEG: arm64")
    set(JPEG_SOURCES
            jpeg/libjpeg-turbo/simd/jsimd_arm64_neon.S
            jpeg/libjpeg-turbo/simd/jsimd_arm64.c )
... ...
else()
    MESSAGE(STATUS "JPEG: else")
    set(JPEG_SOURCES
            jpeg/libjpeg-turbo/jsimd_none.c )
endif()

add_library( jpeg
             STATIC
             jpeg/libjpeg-turbo/jcapimin.c
             jpeg/libjpeg-turbo/jcapistd.c
             jpeg/libjpeg-turbo/jaricom.c
             jpeg/libjpeg-turbo/jcarith.c
             jpeg/libjpeg-turbo/jccoefct.c
             jpeg/libjpeg-turbo/jccolor.c
             jpeg/libjpeg-turbo/jcdctmgr.c
             jpeg/libjpeg-turbo/jchuff.c
             jpeg/libjpeg-turbo/jcinit.c
             jpeg/libjpeg-turbo/jcmainct.c
             jpeg/libjpeg-turbo/jcmarker.c
             jpeg/libjpeg-turbo/jcmaster.c
             jpeg/libjpeg-turbo/jcomapi.c
             jpeg/libjpeg-turbo/jcparam.c
             jpeg/libjpeg-turbo/jcphuff.c
             jpeg/libjpeg-turbo/jcprepct.c
             jpeg/libjpeg-turbo/jcsample.c
             jpeg/libjpeg-turbo/jctrans.c
             jpeg/libjpeg-turbo/jdapimin.c
             jpeg/libjpeg-turbo/jdapistd.c
             jpeg/libjpeg-turbo/jdarith.c
             jpeg/libjpeg-turbo/jdatadst.c
             jpeg/libjpeg-turbo/jdatasrc.c
             jpeg/libjpeg-turbo/jdcoefct.c
             jpeg/libjpeg-turbo/jdcolor.c
             jpeg/libjpeg-turbo/jddctmgr.c
             jpeg/libjpeg-turbo/jdhuff.c
             jpeg/libjpeg-turbo/jdinput.c
             jpeg/libjpeg-turbo/jdmainct.c
             jpeg/libjpeg-turbo/jdmarker.c
             jpeg/libjpeg-turbo/jdmaster.c
             jpeg/libjpeg-turbo/jdmerge.c
             jpeg/libjpeg-turbo/jdphuff.c
             jpeg/libjpeg-turbo/jdpostct.c
             jpeg/libjpeg-turbo/jdsample.c
             jpeg/libjpeg-turbo/jdtrans.c
             jpeg/libjpeg-turbo/jerror.c
             jpeg/libjpeg-turbo/jfdctflt.c
             jpeg/libjpeg-turbo/jfdctfst.c
             jpeg/libjpeg-turbo/jfdctint.c
             jpeg/libjpeg-turbo/jidctflt.c
             jpeg/libjpeg-turbo/jidctfst.c
             jpeg/libjpeg-turbo/jidctint.c
             jpeg/libjpeg-turbo/jidctred.c
             jpeg/libjpeg-turbo/jmemmgr.c
             jpeg/libjpeg-turbo/jmemnobs.c
             jpeg/libjpeg-turbo/jquant1.c
             jpeg/libjpeg-turbo/jquant2.c
             jpeg/libjpeg-turbo/jutils.c
             ${JPEG_SOURCES} )

target_include_directories(jpeg PRIVATE
            jpeg/libjpeg-turbo
            jpeg/libjpeg-turbo/simd )

We also use static libraries here.

  • Decode
#include <jpeglib.h>

#include "JpegTest.h"

void jpgfile_to_jpgmem(char *jpg_file,byte **jpg,int *size)
{
    FILE *fp = fopen(jpg_file,"rb");
    if(fp == NULL) return;

    fseek(fp,0,SEEK_END);
    int length = ftell(fp);
    fseek(fp,0,SEEK_SET);

    *jpg = new byte[length];
    fread(*jpg,length,1,fp);
    *size = length;

    fclose(fp);
}

void jpgmem_to_bgr(byte *jpg,int size,byte **bgr,int *b_size,int *w,int *h)
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_decompress(&cinfo);
    jpeg_mem_src(&cinfo,jpg,size);

    jpeg_read_header(&cinfo,TRUE);
    jpeg_start_decompress(&cinfo);

    unsigned long width = cinfo.output_width;
    unsigned long height = cinfo.output_height;
    unsigned short depth = cinfo.output_components;

    *w = width;
    *h = height;
    *b_size = width*height*depth;
    *bgr = (byte*)malloc(width*height*depth);
    memset(*bgr,0,width*height*depth);

    JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, width*depth,1);

    byte *point = (*bgr)+(height-cinfo.output_scanline-1)*(width*depth);
    while(cinfo.output_scanline<height)
    {
        jpeg_read_scanlines(&cinfo, buffer, 1);
        memcpy(point, *buffer, width*depth);
        point -= width*depth;
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
}

void readJpegFile(char* fileName) {
    byte* jpg = static_cast<byte*> (malloc(1024));
    int size = 0;

    jpgfile_to_jpgmem(fileName, &jpg, &size);

    my_show_byte("Jpeg raw data", jpg, size);

    byte* rgb = static_cast<byte*> (malloc(1024));
    int rgb_size = 0;
    int w = 0;
    int h = 0;
    jpgmem_to_bgr(jpg, size, &rgb, &rgb_size, &w, &h);

    ALOGE("jpgmem_to_bgr rgb_size %d w %d h %d", rgb_size, w, h);

    my_show_byte("Jpeg rgb data", rgb, rgb_size);

    free(rgb);
    free(jpg);
}

Through the jpgfile_to_jpgmem function, the jpg file is converted into the corresponding bytecode.

~ E/PngCodec: png_show_byte Jpeg raw data 1418 bytes 
FFD8FFE000104A464946000101010060
00600000FFDB00430002010102010102
02020202020202030503030303030604
040305070607070706070708090B0908
080A0807070A0D0A0A0B0C0C0C0C0709
... ...

logcat can only play 1024 bytes to

Then through the jpgmem_to_bgr function, the original data of Jpeg is decoded into RGR data:

~E/PngCodec: png_show_byte Jpeg rgb data 48 bytes
 FFFFC69F9E5E4549891216560807005352121317578C90D0

We can write this BGR data into the Bitmap file, and then open the picture browser to see, and the previous Jpeg image is the same.

The code in the instance can be downloaded to github!

Codec-JPGCodec

Posted by lcoscare on Mon, 16 Sep 2019 22:46:22 -0700