diff --git a/docs/CHANGES.TXT b/docs/CHANGES.TXT index d8ae89fa5..3eb16d15e 100644 --- a/docs/CHANGES.TXT +++ b/docs/CHANGES.TXT @@ -2,6 +2,7 @@ ----------------- - BOM is no longer enabled by default on windows platforms - CEA-708: Rust decoder is now default instead of C decoder +- Fix: Mac Build processes 0.93 (2021-08-16) ----------------- @@ -84,7 +85,7 @@ - New: Add support for DVB inside .mkv - Fix: Added -latrusmap Map Latin symbols to Cyrillic ones in special cases of Russian Teletext files (issue #1086) -- Fix: Several OCR crashes +- Fix: Several OCR crashes 0.87 (2018-10-23) ----------------- @@ -164,10 +165,10 @@ - New: Added tarball generation script. - New: Added --analyzevideo. If present the video stream will be processed even if the subtitles are in a different stream. This is useful when we want video information - (resolution, frame type, etc). -vides now implies this option too. + (resolution, frame type, etc). -vides now implies this option too. [Note: Tentative - some possibly breaking changed were made for this, so if you use it validate results] -- New: Added a GUI in the main CCExtractor binary (separate from the external GUIs +- New: Added a GUI in the main CCExtractor binary (separate from the external GUIs such as CCExtractorGUI). - New: A Python binding extension so it's possible to use CCExtractor's tools from Python. @@ -178,29 +179,29 @@ - New: FreeType-based text renderer (-out=spupng with teletext/EIA608). - New: Upgrade library UTF8proc - New: Upgrade library win_iconv -- New: Upgrade library zlib -- New: Upgrade library LibPNG +- New: Upgrade library zlib +- New: Upgrade library LibPNG - New: Support for Source-Specific Multicast -- New: Added Travis CI support +- New: Added Travis CI support - New: Made error messages clearer, less ambiguous - Fix: Prevent the OCR being initialized more than once (happened on multiprogram and PAT changes) - Fix: Makefiles, build scripts, etc... everything updated and corrected for all platforms. - -Fix: Proper line ending for .srt files from bitmaps. -- Fix: OCR corrections using grayscale before extracting texts. + -Fix: Proper line ending for .srt files from bitmaps. +- Fix: OCR corrections using grayscale before extracting texts. - Fix: End timestamps in transcripts from DVB. - Fix: Forcing -noru to cause deduplication in ISDB -- Fix: TS: Skip NULL packets +- Fix: TS: Skip NULL packets - Fix: When NAL decoding fails, don't dump the whole decoded thing, limit to 160 bytes. -- Fix: Modify Autoconf scripts to generate tarball for mac from `/package_creators/tarball.sh` +- Fix: Modify Autoconf scripts to generate tarball for mac from `/package_creators/tarball.sh` and include GUI files in tarball - Fix: Started work on libGPAC upgrade. - Fix: DVB subtitle not extracted if there's no display segment - Fix: Heap corruption in add_ocrtext2str - Fix: bug that caused -out=spupng sometimes crashes -- Fix: Checks for text before newlines on DVB subtitles -- Fix: OCR issue caused by separated dvb subtitle regions +- Fix: Checks for text before newlines on DVB subtitles +- Fix: OCR issue caused by separated dvb subtitle regions - Fix: DVB crash on specific condition (!rect->ocr_text) - Fix: DVB bug (Multiple-line subtitle; Missing last line) - Fix: --sentencecap for teletext samples @@ -247,7 +248,7 @@ 0.84 (2016-12-16) ----------------- -- New: In Windows, both with and without-OCR binaries are bundled, since the OCR one causes problems due to +- New: In Windows, both with and without-OCR binaries are bundled, since the OCR one causes problems due to dependencies in some system. So unless you need the OCR just use the non-OCR version. - New: Added -sbs (sentence by sentence) for DVB output. Each frame in the output file contains a complete sentence (experimental). @@ -270,7 +271,7 @@ - Fix: Added detail in many error messages. - Fix: Memory leaks in videos with XDS. - Fix: Makefile compatibility issues with Raspberry pi. -- Fix: missing separation between WebVTT header and body. +- Fix: missing separation between WebVTT header and body. - Fix: Stupid bug in M2TS that preventing it from working. - Fix: OCR libraries dependencies for the release version in Windows. - Fix: non-buffered reading from pipes. @@ -317,7 +318,7 @@ - Fix: Timing in -ucla - Fix: Timing in ISDB (some instances) - Fix: "mfra" mp4 box weight changed to 1 (this helps with correct file format detection) -- Fix: Fix for TARGET File is null. +- Fix: Fix for TARGET File is null. - Fix: Fixed SegFaults while parsing parameters (if mandatory parameter is not present in -outinterval, -codec or -nocodec) - Fix: Crash when input small is too small - Fix: Update some URLs in code (references to docs) @@ -375,7 +376,7 @@ - CCExtractor can be used as library if compiled using cmake - By default the Windows version adds BOM to generated UTF files (this is because it's needed to open the files correctly) while all other - builds don't add it (because it messes with text processing tools). + builds don't add it (because it messes with text processing tools). You can use -bom and -nobom to change the behaviour. 0.74 (2014-09-24) @@ -414,7 +415,7 @@ ------------------------ This is the first release that is part of Google's Summer of Code. Anshul, Ruslan and Willem joined CCExtractor to work on a number of things -over the summer, and their work is already reaching the mainstream +over the summer, and their work is already reaching the mainstream version of CCExtractor. - Added a huge dictionary submitted by Matt Stockard. @@ -447,7 +448,7 @@ version of CCExtractor. 0000101 is the default setting for transcripts 1110101 is the default for timed transcripts 1111001 is the default setting for -ucla - Make sure you use this parameter after others that might affect these + Make sure you use this parameter after others that might affect these settings (-out, -ucla, -xds, -txt, -ttxt, ...) - Fixed Negative timing Bug @@ -465,7 +466,7 @@ version of CCExtractor. - Started refactoring and clean-up. - Fix: MPEG clock rollover (happens each 26 hours) caused a time discontinuity. -- Windows GUI: Started work on HDHomeRun support. For now it just looks +- Windows GUI: Started work on HDHomeRun support. For now it just looks for HDHomeRun devices. Lots of other things will arrive in the next versions. - Windows GUI: Some code refactoring, since the HDHomeRun support makes @@ -482,7 +483,7 @@ version of CCExtractor. a good test sample file... - Color and fonts in PAC commands were ignored, fixed (Helen Buus). - Added a new output format, spupng. It consists on one .png file - for each subtitle frame and one .xml with all the timing + for each subtitle frame and one .xml with all the timing (Heleen Buus). - Some fixes (Chris Small). @@ -504,12 +505,12 @@ version of CCExtractor. - Added -latin1 to select Latin 1 as encoding. Default is now UTF-8 (-utf8 still exists but it's not needed). - Added -ru1, which emulates a (non-existing in real life) 1 line - roll-up mode. + roll-up mode. 0.66 (2013-07-01) ----------------- -- Fixed bug in auto detection code that triggered a message +- Fixed bug in auto detection code that triggered a message about file being auto of sync. - Added -investigate_packets The PMT is used to select the most promising elementary stream @@ -518,39 +519,39 @@ version of CCExtractor. manually, in case the CC location is not obvious from the PMT contents. To assist looking for the right stream, the parameter "-investigate_packets" will have CCExtractor look inside each - stream, looking for CC markers, and report the streams that + stream, looking for CC markers, and report the streams that are likely to contain CC data even if it can't be determined from their PMT entry. - Added -datastreamtype to manually selecting a stream based on its type instead of its PID. Useful if your recording program - always hides the caption under the stream type. + always hides the caption under the stream type. - Added -streamtype so if an elementary stream is selected manually - for processing, the streamtype can be selected too. This can be - needed if you process, for example a stream that is declared as + for processing, the streamtype can be selected too. This can be + needed if you process, for example a stream that is declared as "private MPEG" in the PMT, so CCExtractor can't tell what it is. Usually you'll want -streamtype 2 (MPEG video) or -streamtype 6 (MPEG private data). - PMT content listing improved, it now shows the stream type for more types. -- Fixes in roll-up, cursor was being moved to column 1 if a +- Fixes in roll-up, cursor was being moved to column 1 if a RU2, RU3 or RU4 was received even if already in roll-up mode. -- Added -autoprogram. If a multiprogram TS is processed and +- Added -autoprogram. If a multiprogram TS is processed and -autoprogram is used, CCExtractor will analyze all PMTs and use the first program that has a suitable data stream. -- Timed transcript (ttxt) now also exports the caption mode - (roll-up, paint-on, etc.) next to each line, as it's useful to +- Timed transcript (ttxt) now also exports the caption mode + (roll-up, paint-on, etc.) next to each line, as it's useful to detect things like commercials. - Content Advisory information from XDS is now decoded if it's - transmitted in "US TV parental guidelines" or "MPA". - Other encoding such as Canada's are not supported yet due + transmitted in "US TV parental guidelines" or "MPA". + Other encoding such as Canada's are not supported yet due to lack of samples. - Copy Management information from XDS is now decoded. - Added -xds. If present and export format is timed transcript (only), XDS information will be saved to file (same file as the transcript, with XDS being clearly marked). Note that for now - all XDS data is exported even if it doesn't change, so the + all XDS data is exported even if it doesn't change, so the transcript file will be significantly larger. -- Added some PaintOn support, at least enough to prevent it +- Added some PaintOn support, at least enough to prevent it from breaking things when the other modes are used. - Removed afd_data() warning. AFD doesn't carry any caption related data. AFD still detected in code in case we want to do something @@ -568,21 +569,21 @@ version of CCExtractor. calculated distance, the maximum allowed distance, and whether the strings are ultimately considered equivalent or not, i.e. the calculated distance is less or equal than the max allowed. - -levdistmincnt value: Minimum distance we always allow - regardless of the length of the strings. Default 2. This means - that if the calculated distance is 0, 1 or 2, we consider the + -levdistmincnt value: Minimum distance we always allow + regardless of the length of the strings. Default 2. This means + that if the calculated distance is 0, 1 or 2, we consider the strings to be equivalent. - -levdistmaxpct value: Maximum distance we allow, as a - percentage of the shortest string length. Default 10%. For - example, consider a comparison of one string of 30 characters - and one of 60 characters. We want to determine whether the - first 30 characters of the longer string are more or less the - same as the shortest string, i.e. whether the longest string - is the shortest one plus new characters and maybe some - corrections. Since the shortest string is 30 characters and - the default percentage is 10%, we would allow a distance of + -levdistmaxpct value: Maximum distance we allow, as a + percentage of the shortest string length. Default 10%. For + example, consider a comparison of one string of 30 characters + and one of 60 characters. We want to determine whether the + first 30 characters of the longer string are more or less the + same as the shortest string, i.e. whether the longest string + is the shortest one plus new characters and maybe some + corrections. Since the shortest string is 30 characters and + the default percentage is 10%, we would allow a distance of up to 3 between the first 30 characters. -- Added -lf : Use UNIX line terminator (LF) instead of Windows (CRLF). +- Added -lf : Use UNIX line terminator (LF) instead of Windows (CRLF). - Added -noautotimeref: Prevent UTC reference from being auto set from the stream data. @@ -592,7 +593,7 @@ version of CCExtractor. - Added end timestamps in timed transcripts - Added support for SMPTE (patch by John Kemp) - Initial support for MPEG2 video tracks inside MP4 files (thanks a - lot to GPAC's Jean who assisted in analyzing the sample and + lot to GPAC's Jean who assisted in analyzing the sample and doing the required changes in GPAC). - Improved MP4 auto detection - Support for PCR if PTS is not available (needed for some teletext @@ -618,7 +619,7 @@ version of CCExtractor. data (bypassing detections). - Added -ru2 and -ru3 to limit the number of visible lines in roll-up captions (bypassing whatever the broadcast says). -- Added support for a .hex (hexadecimal) dump of data. +- Added support for a .hex (hexadecimal) dump of data. - Added support for wtv in Windows. This is done by using a new program (wtvccdump.exe) and a new DirectShow filter (CCExtractorDump.dll) that process the .wtv using DirecShow's filters and export the line 21 data @@ -629,9 +630,9 @@ version of CCExtractor. 0.63 (2012-08-17) ----------------- - Telext support added, by integrating Petr Kutalek's telxcc. Integration is - still quite basic (there's equivalent code from both CCExtractor and - telxcc) and some clean up is needed, but it works. Petr has announced that - he's abandoning telxcc so further development will happen directly in + still quite basic (there's equivalent code from both CCExtractor and + telxcc) and some clean up is needed, but it works. Petr has announced that + he's abandoning telxcc so further development will happen directly in CCExtractor. - Some bug fixes, as usual. @@ -641,14 +642,14 @@ version of CCExtractor. Mac users that sent this. - Hauppauge mode now uses PES timing, needed for files that don't have caption data during all the video (such as in commercial breaks). -- Added -mp4 and -in:mp4 to force the input to be processed as MP4. +- Added -mp4 and -in:mp4 to force the input to be processed as MP4. - CC608 data embedded in a separate stream (as opposed as in the video - stream itself) in MP4 files is now supported (not heavily tested). + stream itself) in MP4 files is now supported (not heavily tested). This should be rather useful since closed captioned files from iTunes use this format. - More CEA-708 work. The debugger is now able to dump the "TV" contents for - the first time. Also, a .srt can be generated, however timing is not quite - good yet (still need to figure out why). + the first time. Also, a .srt can be generated, however timing is not quite + good yet (still need to figure out why). - Added -svc (or --service) to select the CEA-708 services to be processed. For example, -svc 1,2 will process the primary and secondary language services. Valid values are 1-63, where 1 is the primary language, 2 is @@ -663,9 +664,9 @@ version of CCExtractor. - Fix: GCC 3.4.4 can now build CCExtractor. - Fix: Damaged TS packets (those that come with 'error in transport' bit on) are now skipped. -- Fix: Part of the changes for MP4 support (CC packets buffering in - particular) broke some stuff for other files, causing at least very - annoying character duplication. We hope we've fixed it without breaking +- Fix: Part of the changes for MP4 support (CC packets buffering in + particular) broke some stuff for other files, causing at least very + annoying character duplication. We hope we've fixed it without breaking anything but please report). - Some non-interesting cleanup. @@ -676,13 +677,13 @@ version of CCExtractor. code, the stream must be a file (no streaming), etc. - Fix: The Windows version was writing text files with double \r. - Fix: Closed captions blocks with no data could cause a crash. -- Fix: -noru (to generate files without duplicate lines in +- Fix: -noru (to generate files without duplicate lines in roll-up) was broken, with complete lines being missing. -- Fix: bin format not working as input. +- Fix: bin format not working as input. 0.59 (2011-10-07) ----------------- -- More AVC/H.264 work. pic_order_cnt_type != 0 will be processed now. +- More AVC/H.264 work. pic_order_cnt_type != 0 will be processed now. - Fix: Roll-up captions with interruptions for Text (with ResumeTextDisplay in the middle of the caption data) were missing complete lines. - Added a timed text transcript output format, probably only useful for @@ -705,7 +706,7 @@ version of CCExtractor. - Added -stdout => If used, the captions will be sent to stdout (console) instead of file. Combined with -, CCExtractor can work as a filter in a larger process, receiving the stream from stdin and sending the - captions to stdout. + captions to stdout. - Some code clean up, minor refactoring. - Teletext detection (not yet processing). @@ -714,20 +715,20 @@ version of CCExtractor. - Implemented new PTS based mode to order the caption information of AVC/H.264 data streams. The old pic_order_cnt_lsb based method is still available via the -poc or --usepicorder command switches. -- Removed a couple of those annoying "Impossible!" error messages +- Removed a couple of those annoying "Impossible!" error messages that appears when processing some (possibly broken, unsure) files. -- Added -nots --notypesettings to prevent italics and underline +- Added -nots --notypesettings to prevent italics and underline codes from being displayed. -- Note to those not liking the paragraph symbol being used for the +- Note to those not liking the paragraph symbol being used for the music note: Submit a VALID replacement in latin-1. -- Added preliminary support for multiple program TS files. The +- Added preliminary support for multiple program TS files. The parameter --program-number (or -pn) will let you choose which - program number to process. If no number is passed and the TS + program number to process. If no number is passed and the TS file contains more than one, CCExtractor will display a list of found programs and terminate. - Added support (basic, because I only received one sample) for some Hauppauge cards that save CC data in their own format. Use the - parameter -haup to enable it (CCExtractor will display a notice + parameter -haup to enable it (CCExtractor will display a notice if it thinks that it's processing a Hauppauge capture anyway). - Fixed bug in roll-up. - More AVC work, now TS files from echostar that provided garbled @@ -737,7 +738,7 @@ version of CCExtractor. 0.57 (2010-12-16) ----------------- - Bug fixes in the Windows version. Some debug code was unintentionally - left in the released version. + left in the released version. 0.56 (2010-12-09) ----------------- @@ -754,10 +755,10 @@ version of CCExtractor. - Start implementation of EIA-708 decoding (not active yet). - Add -gt / --goptime switch to use GOP timing instead of PTS timing. - Start implementation of AVC/H.264 decoding (not active yet). -- Fixed: The basic problem is that when 24fps movie film gets converted to 30fps NTSC - they repeat every 4th frame. Some pics have 3 fields of CC data with field 3 CC data - belongs to the same channel as field 1. The following pics have the fields reversed - because of the odd number of fields. I used top_field_first to tell when the channels +- Fixed: The basic problem is that when 24fps movie film gets converted to 30fps NTSC + they repeat every 4th frame. Some pics have 3 fields of CC data with field 3 CC data + belongs to the same channel as field 1. The following pics have the fields reversed + because of the odd number of fields. I used top_field_first to tell when the channels are reversed. See Table 6-1 of the SCTE 20 [Paul Fernquist] 0.54 (2009-04-16) @@ -767,9 +768,9 @@ version of CCExtractor. - Improve synchronization of captions for source files with jumps in their time information or gaps in the caption information. -- [R. Abarca] Changed Mac script, it now compiles/link - everything from the /src directory. -- It's now possible to have CCExtractor add credits +- [R. Abarca] Changed Mac script, it now compiles/link + everything from the /src directory. +- It's now possible to have CCExtractor add credits automatically. - Added a feature to add start and end messages (for credits). See help screen for details. @@ -790,13 +791,13 @@ version of CCExtractor. for Raw Captions With Time). This new format allows one file to contain all the available closed caption data instead of just one stream. -- Added --no_progress_bar to disable status +- Added --no_progress_bar to disable status information (mostly used when debugging, as the progress information is annoying in the middle of debug logs). -- The Windows GUI was reported to freeze in some +- The Windows GUI was reported to freeze in some conditions. Fixed. -- The Windows GUI is now targeted for .NET 2.0 +- The Windows GUI is now targeted for .NET 2.0 instead of 3.5. This allows Windows 2000 to run it (there's not .NET 3.5 for Windows 2000), as requested by a couple of key users. @@ -804,17 +805,17 @@ version of CCExtractor. 0.51 (unreleased) ----------------- - Removed -autopad and -goppad, no longer needed. -- In preparation to a new binary format we have - renamed the current .bin to .raw. Raw files +- In preparation to a new binary format we have + renamed the current .bin to .raw. Raw files have only CC data (with no header, timing, etc.). - The input file format (when forced) is now - specified with + specified with -in=format such as -in=ts, -in=raw, -in=ps ... The old switches (-ts, -ps, etc.) still work. The only exception is -bin which has been removed (reserved for the new binary format). Use - -in=raw to process a raw file. + -in=raw to process a raw file. - Removed -d, which when produced a raw file used a DVD format. This has been merged into a new output type "dvdraw". So now instead of using @@ -823,7 +824,7 @@ version of CCExtractor. - Removed --noff - Added gui_mode_reports for frontend communications, see related file. -- Windows GUI rewritten. Source code now included, +- Windows GUI rewritten. Source code now included, too. - [Volker] Dish Network clean-up @@ -836,12 +837,12 @@ version of CCExtractor. 0.49 (2008-12-10) ----------------- - [Volker] Major MPEG parser rework. Code much - cleaner now. + cleaner now. - Some stations transmit broken roll-up captions, and for some reason don't send CRs but RUs... Added work-around code to make captions readable. - Started work on EIA-708 (DTV). Right now you can - add -debug-708 to get a dump of the 708 data. + add -debug-708 to get a dump of the 708 data. An actually useful decoder will come soon. - Some of the changes MIGHT HAVE BROKEN MythTV's code. I don't use MythTV myself so I rely on @@ -857,9 +858,9 @@ version of CCExtractor. can now process files that are being recorded at the same time. -- [Volker] Added a new DVR-MS loop - this is +- [Volker] Added a new DVR-MS loop - this is completely new, DVR-MS specific code, so we no - longer use the generic MPEG code for DVR-MS. + longer use the generic MPEG code for DVR-MS. DVR-MS should (or will be eventually at least) be as reliable as TS. Note: For now, it's only ATSC recordings, not @@ -878,11 +879,11 @@ version of CCExtractor. new options. - Added -lg --largegops From the help screen: - Each Group-of-Picture comes with timing - information. When this info is too separate - (for example because there are a lot of - frames in a GOP) ccextractor may prefer not - to use GOP timing. Use this option is you + Each Group-of-Picture comes with timing + information. When this info is too separate + (for example because there are a lot of + frames in a GOP) ccextractor may prefer not + to use GOP timing. Use this option is you need ccextractor to use GOP timing in large GOPs. @@ -901,8 +902,8 @@ version of CCExtractor. 0.43 (2008-06-20) ----------------- - Fixed a bug in the read loop (no less) - that caused some files to fail when - reading without buffering (which is + that caused some files to fail when + reading without buffering (which is the default in the Linux build). - Several improvements in the GUI, such as saving current options as default. @@ -919,8 +920,8 @@ version of CCExtractor. ----------------- - Default output is now .srt instead of .bin, use -raw if you need the data dump instead of - .srt. -- Added -trim, which removes blank spaces at + .srt. +- Added -trim, which removes blank spaces at the left and rights of each line in .srt. Note that those spaces are there to help deaf people know if the person talking is @@ -930,8 +931,8 @@ version of CCExtractor. 0.40 (2008-05-20) ----------------- -- Fixed a bug in the sanity check function - that caused the Myth branch to abort. +- Fixed a bug in the sanity check function + that caused the Myth branch to abort. - Fixed the OSX build script, it needed a new #define to work. @@ -941,30 +942,30 @@ version of CCExtractor. have no time information. Also, if in roll-up mode there will be no repeated lines. - Lots of changes in the MPEG parser, most of - them submitted by Volker Quetschke. + them submitted by Volker Quetschke. - Fixed a bug in the CC decoder that could cause the first line not to be cleared in roll-up - mode. + mode. - CCExtractor can now follow number sequences in file names, by suffixing the name with +. For example, - DVD0001.VOB+ + DVD0001.VOB+ means DVD0001.VOB, DVD0002.VOB, etc. This works for all files, so part001.ts+ does what you could expect. - Added -90090 which changes the clock frequency - from the MPEG standard 90000 to 90090. It + from the MPEG standard 90000 to 90090. It *could* (remains to be seen) help if there are - timing issues. + timing issues. - Better support for Tivo files. - By default ccextractor now considers the whole input file list a one large file, instead of several, independent, video files. This has been changed because most programs (for example - DVDDecrypt) just cut the files by size. - If you need the old behaviour (because you + DVDDecrypt) just cut the files by size. + If you need the old behaviour (because you actually edited the video files and want to join the subs), use -ve. @@ -982,7 +983,7 @@ version of CCExtractor. that have been added because old behaviour was annoying to most people: _1 and _2 at the end of the output file names is now added ONLY if - -12 is used (i.e. when there are two output + -12 is used (i.e. when there are two output files to produce). So ccextractor -srt sopranos.mpg @@ -1043,7 +1044,7 @@ version of CCExtractor. Alan Tony - So you get + So you get You better respect this robe, Alan. @@ -1052,7 +1053,7 @@ version of CCExtractor. have a different spelling file per TV show, or a large file with a lot of words, etc. -- ccextractor has been reported to +- ccextractor has been reported to compile and run on Mac with a minor change in the build script, so I've created a mac directory with the @@ -1066,17 +1067,17 @@ version of CCExtractor. ----------------- - Added -scr or --screenfuls, to select the number of screenfuls ccextractor should - write before exiting. A screenful is + write before exiting. A screenful is a change of screen contents caused by a CC command (not new characters). In practice, this means that for .srt each group of lines is a screenful, except when - using -dru (which produces a lot of + using -dru (which produces a lot of groups of lines because each new character produces a new group). - Completed tables for all encodings. - Fixed bug in .srt related to milliseconds - in time lines. + in time lines. - Font colors are back for .srt (apparently some programs do support them after all). Use -nofc or --nofontcolor if you don't @@ -1085,7 +1086,7 @@ version of CCExtractor. 0.32 (unreleased) ----------------- - Added -delay ms, which adds (or subtracts) - a number of milliseconds to all times in + a number of milliseconds to all times in .srt/.sami files. For example, -delay 400 @@ -1116,8 +1117,8 @@ version of CCExtractor. - Fix in extended char decoding, I wasn't replacing the previous char. - When a sequence code was found before - having a PTS, reported time was - undefined. + having a PTS, reported time was + undefined. 0.29 (unreleased) ----------------- @@ -1142,7 +1143,7 @@ version of CCExtractor. 0.26 (unreleased) ----------------- - Added -gp (or -goppad) to make ccextractor use - GOP timing. Try it for non TS files where + GOP timing. Try it for non TS files where subs start OK but desync as the video advances. 0.25 (unreleased) @@ -1151,7 +1152,7 @@ version of CCExtractor. -nomyth to prevent the MytvTV code path to be called. I've seen apparently correct files that make MythTV's MPEG decoder to choke. So, if it - doesn't work correctly automatically: Try + doesn't work correctly automatically: Try -nomyth and -myth. Hopefully one of the two options will work. @@ -1164,7 +1165,7 @@ version of CCExtractor. - Reworked input buffer code, faster now. - Completed MythTV's MPEG decoder for Program Streams, which results in better processing of some specific - files. + files. - Automatic file format detection for all kind of files and closed caption storage method. No need to tell ccextractor anything about your file (but you @@ -1173,10 +1174,10 @@ version of CCExtractor. 0.22 (2007-05-15) ----------------- -- Added text mode handling into decoder, which gets rids +- Added text mode handling into decoder, which gets rids of junk when text mode data is present. - Added support for certain (possibly non standard - compliant) DVDs that add more captions block in a + compliant) DVDs that add more captions block in a user data block than they should (such as Red October). - Fix in roll-up init code that caused the previous popup captions not to be written to disk. @@ -1187,13 +1188,13 @@ version of CCExtractor. ----------------- - Unicode should be decent now. - Added support for Hauppauge PVR 250 cards, and (possibly) - many others (bttv) with the same closed caption recording + many others (bttv) with the same closed caption recording format. This is the result of hacking MythTV's MPEG parser into CCExtractor. Integration is not very good (to put it midly) but it seems to work. Depending on the feedback I may continue working on this or just leave it 'as it' - (good enough). + (good enough). If you want to process a file generated by one of these analog cards, use -myth. This is essential as it will make the program take a totally different code path. @@ -1203,10 +1204,10 @@ version of CCExtractor. 0.19 (2007-05-03) ----------------- -- Work on Dish Network streams, timing was completely broken. +- Work on Dish Network streams, timing was completely broken. It's fixed now at least for the samples I have, if it's not completely fixed let me know. Credit for this goes to - Jack Ha who sent me a couple of samples and a first + Jack Ha who sent me a couple of samples and a first implementation of a semi working-fix. - Added support for several input files (see help screen for details). diff --git a/docs/COMPILATION.MD b/docs/COMPILATION.MD index bb4009b1d..5addafd7c 100644 --- a/docs/COMPILATION.MD +++ b/docs/COMPILATION.MD @@ -60,7 +60,7 @@ cd ccextractor/linux sudo apt-get install autoconf #Dependency to generate configuration script cd ccextractor/linux ./autogen.sh -./configure or ./configure --without-rust +./configure # OR ./configure --without-rust make # test your build @@ -74,14 +74,12 @@ sudo make install ```bash #Create and navigate to directory where you want to store built files - cd ccextractor/ mkdir build cd build #Generate makefile using cmake and then compile - -cmake ../src/ +cmake ../src/ # options here make # test your build @@ -91,13 +89,16 @@ make sudo make install ``` -`cmake` also accepts the argument `-DWITH_OCR=ON` to enable OCR and `-DWITHOUT_RUST=ON` to disable rust. +`cmake` also accepts the options: + `-DWITH_OCR=ON` to enable OCR + `-DWITHOUT_RUST=ON` to disable rust. + `-DWITH_HARDSUBX=ON` to enable burned-in subtitles ### Compiling with GUI: -To build CCExtractor with a gui you will additionally need to install [GLEW](http://glew.sourceforge.net/build.html) and [GLFW](http://www.glfw.org/docs/latest/compile.html) +To build CCExtractor with a GUI, you will additionally need to install [GLEW](http://glew.sourceforge.net/build.html) and [GLFW](http://www.glfw.org/docs/latest/compile.html) -In order to compile it you'll need to configure it using autoconf by passing the `-with-gui` option. +In order to compile it, you'll need to configure it using autoconf by passing the `-with-gui` option. ```bash ./autogen.sh @@ -112,16 +113,18 @@ Once set up you can run the GUI interface from the terminal `./ccextractorGUI` ## macOS -1. Make sure all the dependencies are met. They can be installed via Homebrew as +1. Make sure all the dependencies are met. Decide if you want OCR; if so, you'll need to install tesseract and leptonica. +Dependencies can be installed via Homebrew as: ```bash brew install pkg-config brew install autoconf automake libtool +# optional if you want OCR: brew install tesseract brew install leptonica ``` -Use pkg-config to verify tesseract and leptonica dependencies, e.g. +If configuring OCR, use pkg-config to verify tesseract and leptonica dependencies, e.g. ```bash pkg-config --exists --print-errors tesseract @@ -134,17 +137,7 @@ pkg-config --exists --print-errors lept ```bash cd ccextractor/mac -./build.command OCR - -# test your build -./ccextractor -``` - -If you don't want the OCR capabilities, then you don't need to configure the tesseract and leptonica packages, and build it with just - -```bash -cd ccextractor/mac -./build.command +./build.command # OR ./build.command OCR # test your build ./ccextractor @@ -154,26 +147,29 @@ cd ccextractor/mac ```bash #Create and navigate to directory where you want to store built files - cd ccextractor/ mkdir build cd build #Generate makefile using cmake and then compile - -cmake ../src/ +cmake ../src/ # options here make # test your build ./ccextractor ``` +`cmake` also accepts the options: + `-DWITH_OCR=ON` to enable OCR + `-DWITHOUT_RUST=ON` to disable rust. + `-DWITH_HARDSUBX=ON` to enable burned-in subtitles + #### Standard compilation through Autoconf scripts: ```bash cd ccextractor/mac ./autogen.sh -./configure +./configure # OR .configure --without-rust make # test your build @@ -189,15 +185,15 @@ brew install glfw brew install glew ``` -In order to compile it you'll need to configure it using autoconf by passing the `-with-gui` option. +In order to compile it, you'll need to configure it using autoconf by passing the `-with-gui` option. ```bash ./autogen.sh -./configure --with-gui +./configure --with-gui #OR .configure --with-gui --without-rust make ``` -Once set up you can run the GUI interface from the terminal `./ccextractorGUI` +Once set up, you can run the GUI interface from the terminal `./ccextractorGUI` ## Windows Note: Following screenshots and steps are based on Visual Studio 2017, but they should be more or less same for other versions. diff --git a/linux/Makefile.am b/linux/Makefile.am index 1f236eec8..b6bcb0cea 100644 --- a/linux/Makefile.am +++ b/linux/Makefile.am @@ -262,7 +262,7 @@ ccextractor_SOURCES = \ ../src/thirdparty/lib_hash/sha2.h \ ../src/thirdparty/protobuf-c/protobuf-c.c \ ../src/thirdparty/protobuf-c/protobuf-c.h \ - ../src/thirdparty/zvbi/bcd.h \ + ../src/lib_ccx/zvbi/bcd.h \ ../src/lib_ccx/zvbi/bit_slicer.c \ ../src/lib_ccx/zvbi/bit_slicer.h \ ../src/lib_ccx/zvbi/decoder.c \ @@ -274,7 +274,7 @@ ccextractor_SOURCES = \ ../src/lib_ccx/zvbi/sampling_par.h \ ../src/lib_ccx/zvbi/sliced.h \ ../src/lib_ccx/zvbi/zvbi_decoder.h \ - ../src/freetype/* \ + ../src/freetype/* \ ../src/thirdparty/freetype/autofit/autofit.c \ ../src/thirdparty/freetype/base/ftbase.c \ ../src/thirdparty/freetype/base/ftbbox.c \ @@ -303,7 +303,7 @@ ccextractor_SOURCES = \ ../src/thirdparty/freetype/cff/cff.c \ ../src/thirdparty/freetype/cid/type1cid.c \ ../src/thirdparty/freetype/gzip/ftgzip.c \ - ../src/thirdparty/freetype/include/ft2build.h \ + ../src/thirdparty/freetype/include/ft2build.h \ ../src/thirdparty/freetype/lzw/ftlzw.c \ ../src/thirdparty/freetype/pcf/pcf.c \ ../src/thirdparty/freetype/pfr/pfr.c \ @@ -318,9 +318,15 @@ ccextractor_SOURCES = \ ../src/thirdparty/freetype/type42/type42.c \ ../src/thirdparty/freetype/winfonts/winfnt.c +if SYS_IS_APPLE_SILICON +ccextractor_SOURCES += ../src/thirdparty/libpng/arm/arm_init.c \ + ../src/thirdparty/libpng/arm/filter_neon_intrinsics.c \ + ../src/thirdparty/libpng/arm/palette_neon_intrinsics.c +endif + ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H -ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/thirdparty/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/ +ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/ ccextractor_LDADD=-lm -lpthread -ldl @@ -348,7 +354,7 @@ endif if SYS_IS_MAC ccextractor_CFLAGS += -DPAC_CONFIG_DARWIN -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -ccextractor_LDADD += -liconv -lz +ccextractor_LDADD += -liconv -lz endif if SYS_IS_64_BIT @@ -445,7 +451,7 @@ endif if HARDSUBX_IS_ENABLED if OCR_IS_ENABLED -ccextractorGUI_CFLAGS += -DENABLE_OCR +ccextractorGUI_CFLAGS += -DENABLE_OCR endif endif diff --git a/linux/configure.ac b/linux/configure.ac index 6911cbad6..fcf57bc20 100644 --- a/linux/configure.ac +++ b/linux/configure.ac @@ -158,6 +158,7 @@ AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silen AM_CONDITIONAL(TESSERACT_PRESENT_RPI, [ test -d "/usr/include/tesseract" && test `ls -A /usr/include/tesseract | wc -l` -gt 0 ]) AM_CONDITIONAL(SYS_IS_LINUX, [ test `uname -s` = "Linux"]) AM_CONDITIONAL(SYS_IS_MAC, [ test `uname -s` = "Darwin"]) +AM_CONDITIONAL(SYS_IS_APPLE_SILICON, [ test `uname -a | awk '{print $NF}'` = "arm64" ]) AM_CONDITIONAL(BUILD_WITH_GUI, [test "x$with_gui" = "xyes"]) AM_CONDITIONAL(SYS_IS_64_BIT,[test `getconf LONG_BIT` = "64"]) diff --git a/mac/Makefile.am b/mac/Makefile.am index 74949e5be..b6bcb0cea 100644 --- a/mac/Makefile.am +++ b/mac/Makefile.am @@ -1,5 +1,5 @@ AUTOMAKE_OPTIONS = foreign - +ACLOCAL_AMFLAGS = -I m4/ bin_PROGRAMS = ccextractor ccextractor_SOURCES = \ @@ -80,6 +80,7 @@ ccextractor_SOURCES = \ ../src/thirdparty/gpacmp4/gpac/tools.h \ ../src/thirdparty/gpacmp4/gpac/utf.h \ ../src/thirdparty/gpacmp4/gpac/version.h \ + ../src/thirdparty/gpacmp4/gpac/iso639.h \ ../src/thirdparty/gpacmp4/gpac/internal/avilib.h \ ../src/thirdparty/gpacmp4/gpac/internal/isomedia_dev.h \ ../src/thirdparty/gpacmp4/gpac/internal/media_dev.h \ @@ -261,18 +262,19 @@ ccextractor_SOURCES = \ ../src/thirdparty/lib_hash/sha2.h \ ../src/thirdparty/protobuf-c/protobuf-c.c \ ../src/thirdparty/protobuf-c/protobuf-c.h \ - ../src/thirdparty/zvbi/bcd.h \ - ../src/thirdparty/zvbi/bit_slicer.c \ - ../src/thirdparty/zvbi/bit_slicer.h \ - ../src/thirdparty/zvbi/decoder.c \ - ../src/thirdparty/zvbi/macros.h \ - ../src/thirdparty/zvbi/misc.h \ - ../src/thirdparty/zvbi/raw_decoder.c \ - ../src/thirdparty/zvbi/raw_decoder.h \ - ../src/thirdparty/zvbi/sampling_par.c \ - ../src/thirdparty/zvbi/sampling_par.h \ - ../src/thirdparty/zvbi/sliced.h \ - ../src/thirdparty/zvbi/zvbi_decoder.h \ + ../src/lib_ccx/zvbi/bcd.h \ + ../src/lib_ccx/zvbi/bit_slicer.c \ + ../src/lib_ccx/zvbi/bit_slicer.h \ + ../src/lib_ccx/zvbi/decoder.c \ + ../src/lib_ccx/zvbi/macros.h \ + ../src/lib_ccx/zvbi/misc.h \ + ../src/lib_ccx/zvbi/raw_decoder.c \ + ../src/lib_ccx/zvbi/raw_decoder.h \ + ../src/lib_ccx/zvbi/sampling_par.c \ + ../src/lib_ccx/zvbi/sampling_par.h \ + ../src/lib_ccx/zvbi/sliced.h \ + ../src/lib_ccx/zvbi/zvbi_decoder.h \ + ../src/freetype/* \ ../src/thirdparty/freetype/autofit/autofit.c \ ../src/thirdparty/freetype/base/ftbase.c \ ../src/thirdparty/freetype/base/ftbbox.c \ @@ -301,6 +303,7 @@ ccextractor_SOURCES = \ ../src/thirdparty/freetype/cff/cff.c \ ../src/thirdparty/freetype/cid/type1cid.c \ ../src/thirdparty/freetype/gzip/ftgzip.c \ + ../src/thirdparty/freetype/include/ft2build.h \ ../src/thirdparty/freetype/lzw/ftlzw.c \ ../src/thirdparty/freetype/pcf/pcf.c \ ../src/thirdparty/freetype/pfr/pfr.c \ @@ -314,22 +317,48 @@ ccextractor_SOURCES = \ ../src/thirdparty/freetype/type1/type1.c \ ../src/thirdparty/freetype/type42/type42.c \ ../src/thirdparty/freetype/winfonts/winfnt.c - + +if SYS_IS_APPLE_SILICON +ccextractor_SOURCES += ../src/thirdparty/libpng/arm/arm_init.c \ + ../src/thirdparty/libpng/arm/filter_neon_intrinsics.c \ + ../src/thirdparty/libpng/arm/palette_neon_intrinsics.c +endif ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H -ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/thirdparty/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c -I../src/thirdparty -I../src -I../src/thirdparty/freetype/include +ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/ ccextractor_LDADD=-lm -lpthread -ldl +if WITH_RUST +ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a +else +ccextractor_CFLAGS += -DDISABLE_RUST +ccextractor_CPPFLAGS += -DDISABLE_RUST +endif + +if DEBUG_RELEASE +CARGO_RELEASE_ARGS= +else +CARGO_RELEASE_ARGS=--release +endif + +./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a: + cd ../src/rust && \ + CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(CARGO_RELEASE_ARGS); + if SYS_IS_LINUX ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX endif if SYS_IS_MAC ccextractor_CFLAGS += -DPAC_CONFIG_DARWIN -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -ccextractor_LDADD += -liconv -lz +ccextractor_LDADD += -liconv -lz +endif + +if SYS_IS_64_BIT +ccextractor_CFLAGS += -DGPAC_64_BITS endif if HARDSUBX_IS_ENABLED @@ -417,12 +446,12 @@ ccextractorGUI_CFLAGS += -O3 -DUNIX ccextractorGUI_CFLAGS += ${glew_CFLAGS} ccextractorGUI_LDADD += ${glew_LIBS} ccextractorGUI_LDFLAGS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo -ccextractorGUI_LDADD += -lm -L/usr/local/lib -lpthread +ccextractorGUI_LDADD += -lglfw -lm -L/usr/local/lib -lpthread endif if HARDSUBX_IS_ENABLED if OCR_IS_ENABLED -ccextractorGUI_CFLAGS += -DENABLE_OCR +ccextractorGUI_CFLAGS += -DENABLE_OCR endif endif diff --git a/mac/build.command b/mac/build.command index 87a20ecea..4f86630d7 100755 --- a/mac/build.command +++ b/mac/build.command @@ -1,8 +1,8 @@ #!/bin/bash cd `dirname $0` -BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_DARWIN -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H" +BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_DARWIN -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H -DDISABLE_RUST" [[ $1 = "OCR" ]] && BLD_FLAGS="$BLD_FLAGS -DENABLE_OCR" -BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/gpacmp4 -I../src/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/protobuf-c -I../src/thirdparty/zlib -I../src/thirdparty/zvbi -I../src/thirdparty/freetype/include" +BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/gpacmp4 -I../src/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/protobuf-c -I../src/thirdparty/zlib -I../src/thirdparty/freetype/include" [[ $1 = "OCR" ]] && BLD_INCLUDE="$BLD_INCLUDE `pkg-config --cflags --silence-errors tesseract`" SRC_CCX="$(find ../src/lib_ccx -name '*.c')" SRC_GPAC="$(find ../src/thirdparty/gpacmp4 -name '*.c')" @@ -11,7 +11,6 @@ SRC_LIBPNG="$(find ../src/thirdparty/libpng -name '*.c')" SRC_PROTOBUF="$(find ../src/thirdparty/protobuf-c -name '*.c')" SRC_UTF8="../src/thirdparty/utf8proc/utf8proc.c" SRC_ZLIB="$(find ../src/thirdparty/zlib -name '*.c')" -SRC_ZVBI="$(find ../src/thirdparty/zvbi -name '*.c')" SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c \ ../src/thirdparty/freetype/base/ftbase.c \ ../src/thirdparty/freetype/base/ftbbox.c \ diff --git a/mac/configure.ac b/mac/configure.ac index 4f23dd96e..4359c5950 100644 --- a/mac/configure.ac +++ b/mac/configure.ac @@ -1,12 +1,12 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_PREREQ([2.69]) -AC_INIT([CCExtractor], [0.93], [carlos@ccextractor.org]) +AC_PREREQ([2.71]) +AC_INIT([CCExtractor],[0.93],[carlos@ccextractor.org]) AC_CONFIG_AUX_DIR([build-conf]) AC_CONFIG_SRCDIR([../src/ccextractor.c]) AM_INIT_AUTOMAKE([foreign subdir-objects]) - +AC_CONFIG_MACRO_DIRS([m4]) # Checks for programs. AC_PROG_CC @@ -63,7 +63,7 @@ AC_CHECK_FUNCS([floor ftruncate gethostbyname gettimeofday inet_ntoa mblen memch # Checks for arguments with configure AC_ARG_ENABLE([hardsubx], -AC_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard subtitles)]), +AS_HELP_STRING([--enable-hardsubx],[Enables extraction of burnt subtitles (hard subtitles)]), [case "${enableval}" in yes) hardsubx=true ;; no) hardsubx=false ;; @@ -71,7 +71,7 @@ AC_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard esac],[hardsubx=false]) AC_ARG_ENABLE([ocr], -AC_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]), +AS_HELP_STRING([--enable-ocr],[Enables Optical Character Recognition]), [case "${enableval}" in yes) ocr=true ;; no) ocr=false ;; @@ -79,7 +79,7 @@ AC_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]), esac],[ocr=false]) AC_ARG_ENABLE([ffmpeg], -AC_HELP_STRING([--enable-ffmpeg], [Enable FFmpeg integration]), +AS_HELP_STRING([--enable-ffmpeg],[Enable FFmpeg integration]), [case "${enableval}" in yes) ffmpeg=true ;; no) ffmpeg=false ;; @@ -87,12 +87,55 @@ AC_HELP_STRING([--enable-ffmpeg], [Enable FFmpeg integration]), esac],[ffmpeg=false]) AC_ARG_WITH([gui], -AC_HELP_STRING([--with-gui], [Builds CCExtractor with GUI (requires GLFW and GLEW)]), +AS_HELP_STRING([--with-gui],[Builds CCExtractor with GUI (requires GLFW and GLEW)]), [PKG_CHECK_MODULES([glfw3], [glfw3]) && PKG_CHECK_MODULES([glew], [glew])], [with_gui=no]) +#Add argument for rust +AC_ARG_WITH([rust], +AS_HELP_STRING([--with-rust],[Builds CCExtractor with rust library]), +[with_rust=$withval], +[with_rust=yes]) + +AC_MSG_CHECKING(whether to build with rust library) +if test "x$with_rust" = "xyes" ; then + AC_MSG_RESULT(yes) + + #Check if cargo and rust is installed + AC_PATH_PROG([CARGO], [cargo], [notfound]) + AS_IF([test "$CARGO" = "notfound"], [AC_MSG_ERROR([cargo is required])]) + + AC_PATH_PROG([RUSTC], [rustc], [notfound]) + AS_IF([test "$RUSTC" = "notfound"], [AC_MSG_ERROR([rustc is required])]) + + rustc_version=$(rustc --version) + MSRV="1.54.0" + AX_COMPARE_VERSION($rustc_version, [ge], [$MSRV], + [AC_MSG_RESULT(rustc >= $MSRV)], + [AC_MSG_ERROR([Minimum supported rust version(MSRV) is $MSRV, please upgrade rust])]) +else + AC_MSG_RESULT(no) +fi +AM_CONDITIONAL([WITH_RUST], [test "x$with_rust" = "xyes"]) + +AC_ARG_ENABLE(debug, + AS_HELP_STRING([--enable-debug],[Build Rust code with debugging information [default=no]]), + [debug_release=$enableval], + [debug_release=no]) + +AC_MSG_CHECKING(whether to build Rust code with debugging information) +if test "x$debug_release" = "xyes" ; then + AC_MSG_RESULT(yes) + RUST_TARGET_SUBDIR=debug +else + AC_MSG_RESULT(no) + RUST_TARGET_SUBDIR=release +fi +AM_CONDITIONAL([DEBUG_RELEASE], [test "x$debug_release" = "xyes"]) + +AC_SUBST([RUST_TARGET_SUBDIR]) -#Checks and prompts if libraries found/not found to avoild failure while building +#Checks and prompts if libraries found/not found to avoid failure while building AS_IF([ test x$hardsubx = xtrue && test $HAS_AVCODEC -gt 0 ], [AC_MSG_NOTICE(avcodec library found)]) AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVCODEC -gt 0 ], [AC_MSG_ERROR(avcodec library not found. Please install the avcodec library before proceeding)]) AS_IF([ test x$hardsubx = xtrue && test $HAS_AVFORMAT -gt 0 ], [AC_MSG_NOTICE(avformat library found)]) @@ -110,11 +153,13 @@ AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test ! $HAS_LEPT -gt AM_CONDITIONAL(HARDSUBX_IS_ENABLED, [ test x$hardsubx = xtrue ]) AM_CONDITIONAL(OCR_IS_ENABLED, [ test x$ocr = xtrue || test x$hardsubx = xtrue ]) AM_CONDITIONAL(FFMPEG_IS_ENABLED, [ test x$ffmpeg = xtrue ]) -AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silence-errors tesseract`]) +AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silence-errors tesseract` ]) AM_CONDITIONAL(TESSERACT_PRESENT_RPI, [ test -d "/usr/include/tesseract" && test `ls -A /usr/include/tesseract | wc -l` -gt 0 ]) AM_CONDITIONAL(SYS_IS_LINUX, [ test `uname -s` = "Linux"]) AM_CONDITIONAL(SYS_IS_MAC, [ test `uname -s` = "Darwin"]) +AM_CONDITIONAL(SYS_IS_APPLE_SILICON, [ test `uname -a | awk '{print $NF}'` = "arm64" ]) AM_CONDITIONAL(BUILD_WITH_GUI, [test "x$with_gui" = "xyes"]) +AM_CONDITIONAL(SYS_IS_64_BIT,[test `getconf LONG_BIT` = "64"]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/mac/m4/ax_compare_version.m4 b/mac/m4/ax_compare_version.m4 new file mode 100644 index 000000000..ffb4997e8 --- /dev/null +++ b/mac/m4/ax_compare_version.m4 @@ -0,0 +1,177 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# +# DESCRIPTION +# +# This macro compares two version strings. Due to the various number of +# minor-version numbers that can exist, and the fact that string +# comparisons are not compatible with numeric comparisons, this is not +# necessarily trivial to do in a autoconf script. This macro makes doing +# these comparisons easy. +# +# The six basic comparisons are available, as well as checking equality +# limited to a certain number of minor-version levels. +# +# The operator OP determines what type of comparison to do, and can be one +# of: +# +# eq - equal (test A == B) +# ne - not equal (test A != B) +# le - less than or equal (test A <= B) +# ge - greater than or equal (test A >= B) +# lt - less than (test A < B) +# gt - greater than (test A > B) +# +# Additionally, the eq and ne operator can have a number after it to limit +# the test to that number of minor versions. +# +# eq0 - equal up to the length of the shorter version +# ne0 - not equal up to the length of the shorter version +# eqN - equal up to N sub-version levels +# neN - not equal up to N sub-version levels +# +# When the condition is true, shell commands ACTION-IF-TRUE are run, +# otherwise shell commands ACTION-IF-FALSE are run. The environment +# variable 'ax_compare_version' is always set to either 'true' or 'false' +# as well. +# +# Examples: +# +# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) +# +# would both be true. +# +# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) +# +# would both be false. +# +# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) +# +# would be true because it is only comparing two minor versions. +# +# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) +# +# would be true because it is only comparing the lesser number of minor +# versions of the two values. +# +# Note: The characters that separate the version numbers do not matter. An +# empty string is the same as version 0. OP is evaluated by autoconf, not +# configure, so must be a string, not a variable. +# +# The author would like to acknowledge Guido Draheim whose advice about +# the m4_case and m4_ifvaln functions make this macro only include the +# portions necessary to perform the specific comparison specified by the +# OP argument in the final configure script. +# +# LICENSE +# +# Copyright (c) 2008 Tim Toolan +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 13 + +dnl ######################################################################### +AC_DEFUN([AX_COMPARE_VERSION], [ + AC_REQUIRE([AC_PROG_AWK]) + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + AS_VAR_PUSHDEF([A],[ax_compare_version_A]) + A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + AS_VAR_PUSHDEF([B],[ax_compare_version_B]) + B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary + dnl # then the first line is used to determine if the condition is true. + dnl # The sed right after the echo is to remove any indented white space. + m4_case(m4_tolower($2), + [lt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [gt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [le],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ], + [ge],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ],[ + dnl Split the operator from the subversion count if present. + m4_bmatch(m4_substr($2,2), + [0],[ + # A count of zero means use the length of the shorter version. + # Determine the number of characters in A and B. + ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` + ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` + + # Set A to no more than B's length and B to no more than A's length. + A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` + B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` + ], + [[0-9]+],[ + # A count greater than zero means use only that many subversions + A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + ], + [.+],[ + AC_WARNING( + [invalid OP numeric parameter: $2]) + ],[]) + + # Pad zeros at end of numbers to make same length. + ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" + B="$B`echo $A | sed 's/./0/g'`" + A="$ax_compare_version_tmp_A" + + # Check for equality or inequality as necessary. + m4_case(m4_tolower(m4_substr($2,0,2)), + [eq],[ + test "x$A" = "x$B" && ax_compare_version=true + ], + [ne],[ + test "x$A" != "x$B" && ax_compare_version=true + ],[ + AC_WARNING([invalid OP parameter: $2]) + ]) + ]) + + AS_VAR_POPDEF([A])dnl + AS_VAR_POPDEF([B])dnl + + dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. + if test "$ax_compare_version" = "true" ; then + m4_ifvaln([$4],[$4],[:])dnl + m4_ifvaln([$5],[else $5])dnl + fi +]) dnl AX_COMPARE_VERSION diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e4e8e024..cd633c981 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,7 +44,11 @@ configure_file ( add_definitions(-DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H) if(UNIX) - add_definitions(-DGPAC_CONFIG_LINUX) + if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + add_definitions(-DGPAC_CONFIG_DARWIN) + else () + add_definitions(-DGPAC_CONFIG_LINUX) + endif() endif(UNIX) if(CMAKE_SIZEOF_VOID_P EQUAL 8) @@ -59,6 +63,12 @@ include_directories(${PROJECT_SOURCE_DIR}/thirdparty/gpacmp4) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/protobuf-c) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/lib_hash) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libpng) + +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm64") + include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libpng/arm) + aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/libpng/arm SOURCEFILE) +endif () + include_directories(${PROJECT_SOURCE_DIR}/thirdparty/zlib) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/freetype/include) aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/gpacmp4/ SOURCEFILE) diff --git a/src/thirdparty/libpng/arm/arm_init.c b/src/thirdparty/libpng/arm/arm_init.c new file mode 100644 index 000000000..a34ecdbef --- /dev/null +++ b/src/thirdparty/libpng/arm/arm_init.c @@ -0,0 +1,136 @@ + +/* arm_init.c - NEON optimised filter functions + * + * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2014,2016 Glenn Randers-Pehrson + * Written by Mans Rullgard, 2011. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are + * called. + */ +#define _POSIX_SOURCE 1 + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +#if PNG_ARM_NEON_OPT > 0 +#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ +/* WARNING: it is strongly recommended that you do not build libpng with + * run-time checks for CPU features if at all possible. In the case of the ARM + * NEON instructions there is no processor-specific way of detecting the + * presence of the required support, therefore run-time detection is extremely + * OS specific. + * + * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing + * a fragment of C source code which defines the png_have_neon function. There + * are a number of implementations in contrib/arm-neon, but the only one that + * has partial support is contrib/arm-neon/linux.c - a generic Linux + * implementation which reads /proc/cpufino. + */ +#ifndef PNG_ARM_NEON_FILE +# ifdef __linux__ +# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" +# endif +#endif + +#ifdef PNG_ARM_NEON_FILE + +#include /* for sig_atomic_t */ +static int png_have_neon(png_structp png_ptr); +#include PNG_ARM_NEON_FILE + +#else /* PNG_ARM_NEON_FILE */ +# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks" +#endif /* PNG_ARM_NEON_FILE */ +#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ + +#ifndef PNG_ALIGNED_MEMORY_SUPPORTED +# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" +#endif + +void +png_init_filter_functions_neon(png_structp pp, unsigned int bpp) +{ + /* The switch statement is compiled in for ARM_NEON_API, the call to + * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined + * the check is only performed if the API has not set the NEON option on + * or off explicitly. In this case the check controls what happens. + * + * If the CHECK is not compiled in and the option is UNSET the behavior prior + * to 1.6.7 was to use the NEON code - this was a bug caused by having the + * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, + * as documented in png.h + */ + png_debug(1, "in png_init_filter_functions_neon"); +#ifdef PNG_ARM_NEON_API_SUPPORTED + switch ((pp->options >> PNG_ARM_NEON) & 3) + { + case PNG_OPTION_UNSET: + /* Allow the run-time check to execute if it has been enabled - + * thus both API and CHECK can be turned on. If it isn't supported + * this case will fall through to the 'default' below, which just + * returns. + */ +#endif /* PNG_ARM_NEON_API_SUPPORTED */ +#ifdef PNG_ARM_NEON_CHECK_SUPPORTED + { + static volatile sig_atomic_t no_neon = -1; /* not checked */ + + if (no_neon < 0) + no_neon = !png_have_neon(pp); + + if (no_neon) + return; + } +#ifdef PNG_ARM_NEON_API_SUPPORTED + break; +#endif +#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ + +#ifdef PNG_ARM_NEON_API_SUPPORTED + default: /* OFF or INVALID */ + return; + + case PNG_OPTION_ON: + /* Option turned on */ + break; + } +#endif + + /* IMPORTANT: any new external functions used here must be declared using + * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the + * 'prefix' option to configure works: + * + * ./configure --with-libpng-prefix=foobar_ + * + * Verify you have got this right by running the above command, doing a build + * and examining pngprefix.h; it must contain a #define for every external + * function you add. (Notice that this happens automatically for the + * initialization function.) + */ + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; + + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth3_neon; + } + + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth4_neon; + } +} +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* READ */ diff --git a/src/thirdparty/libpng/arm/filter_neon.S b/src/thirdparty/libpng/arm/filter_neon.S new file mode 100644 index 000000000..2308aad13 --- /dev/null +++ b/src/thirdparty/libpng/arm/filter_neon.S @@ -0,0 +1,253 @@ + +/* filter_neon.S - NEON optimised filter functions + * + * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2014,2017 Glenn Randers-Pehrson + * Written by Mans Rullgard, 2011. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* This is required to get the symbol renames, which are #defines, and the + * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION. + */ +#define PNG_VERSION_INFO_ONLY +#include "../pngpriv.h" + +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ +#endif + +#ifdef PNG_READ_SUPPORTED + +/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for + * ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it + * only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h + * for the logic which sets PNG_USE_ARM_NEON_ASM: + */ +#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */ + +#if PNG_ARM_NEON_OPT > 0 + +#ifdef __ELF__ +# define ELF +#else +# define ELF @ +#endif + + .arch armv7-a + .fpu neon + +.macro func name, export=0 + .macro endfunc +ELF .size \name, . - \name + .endfunc + .purgem endfunc + .endm + .text + + /* Explicitly specifying alignment here because some versions of + * GAS don't align code correctly. This is harmless in correctly + * written versions of GAS. + */ + .align 2 + + .if \export + .global \name + .endif +ELF .type \name, STT_FUNC + .func \name +\name: +.endm + +func png_read_filter_row_sub4_neon, export=1 + ldr r3, [r0, #4] @ rowbytes + vmov.i8 d3, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vadd.u8 d0, d3, d4 + vadd.u8 d1, d0, d5 + vadd.u8 d2, d1, d6 + vadd.u8 d3, d2, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r3, r3, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_sub3_neon, export=1 + ldr r3, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + mov r0, r1 + mov r2, #3 + mov r12, #12 + vld1.8 {q11}, [r0], r12 +1: + vext.8 d5, d22, d23, #3 + vadd.u8 d0, d3, d22 + vext.8 d6, d22, d23, #6 + vadd.u8 d1, d0, d5 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], r12 + vst1.32 {d0[0]}, [r1,:32], r2 + vadd.u8 d2, d1, d6 + vst1.32 {d1[0]}, [r1], r2 + vadd.u8 d3, d2, d7 + vst1.32 {d2[0]}, [r1], r2 + vst1.32 {d3[0]}, [r1], r2 + subs r3, r3, #12 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_up_neon, export=1 + ldr r3, [r0, #4] @ rowbytes +1: + vld1.8 {q0}, [r1,:128] + vld1.8 {q1}, [r2,:128]! + vadd.u8 q0, q0, q1 + vst1.8 {q0}, [r1,:128]! + subs r3, r3, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_avg4_neon, export=1 + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! + vhadd.u8 d0, d3, d16 + vadd.u8 d0, d0, d4 + vhadd.u8 d1, d0, d17 + vadd.u8 d1, d1, d5 + vhadd.u8 d2, d1, d18 + vadd.u8 d2, d2, d6 + vhadd.u8 d3, d2, d19 + vadd.u8 d3, d3, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r12, r12, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_avg3_neon, export=1 + push {r4,lr} + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + mov r0, r1 + mov r4, #3 + mov lr, #12 + vld1.8 {q11}, [r0], lr +1: + vld1.8 {q10}, [r2], lr + vext.8 d5, d22, d23, #3 + vhadd.u8 d0, d3, d20 + vext.8 d17, d20, d21, #3 + vadd.u8 d0, d0, d22 + vext.8 d6, d22, d23, #6 + vhadd.u8 d1, d0, d17 + vext.8 d18, d20, d21, #6 + vadd.u8 d1, d1, d5 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], lr + vst1.32 {d0[0]}, [r1,:32], r4 + vhadd.u8 d2, d1, d18 + vst1.32 {d1[0]}, [r1], r4 + vext.8 d19, d21, d21, #1 + vadd.u8 d2, d2, d6 + vhadd.u8 d3, d2, d19 + vst1.32 {d2[0]}, [r1], r4 + vadd.u8 d3, d3, d7 + vst1.32 {d3[0]}, [r1], r4 + subs r12, r12, #12 + bgt 1b + + pop {r4,pc} +endfunc + +.macro paeth rx, ra, rb, rc + vaddl.u8 q12, \ra, \rb @ a + b + vaddl.u8 q15, \rc, \rc @ 2*c + vabdl.u8 q13, \rb, \rc @ pa + vabdl.u8 q14, \ra, \rc @ pb + vabd.u16 q15, q12, q15 @ pc + vcle.u16 q12, q13, q14 @ pa <= pb + vcle.u16 q13, q13, q15 @ pa <= pc + vcle.u16 q14, q14, q15 @ pb <= pc + vand q12, q12, q13 @ pa <= pb && pa <= pc + vmovn.u16 d28, q14 + vmovn.u16 \rx, q12 + vbsl d28, \rb, \rc + vbsl \rx, \ra, d28 +.endm + +func png_read_filter_row_paeth4_neon, export=1 + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + vmov.i8 d20, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! + paeth d0, d3, d16, d20 + vadd.u8 d0, d0, d4 + paeth d1, d0, d17, d16 + vadd.u8 d1, d1, d5 + paeth d2, d1, d18, d17 + vadd.u8 d2, d2, d6 + paeth d3, d2, d19, d18 + vmov d20, d19 + vadd.u8 d3, d3, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r12, r12, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_paeth3_neon, export=1 + push {r4,lr} + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + vmov.i8 d4, #0 + mov r0, r1 + mov r4, #3 + mov lr, #12 + vld1.8 {q11}, [r0], lr +1: + vld1.8 {q10}, [r2], lr + paeth d0, d3, d20, d4 + vext.8 d5, d22, d23, #3 + vadd.u8 d0, d0, d22 + vext.8 d17, d20, d21, #3 + paeth d1, d0, d17, d20 + vst1.32 {d0[0]}, [r1,:32], r4 + vext.8 d6, d22, d23, #6 + vadd.u8 d1, d1, d5 + vext.8 d18, d20, d21, #6 + paeth d2, d1, d18, d17 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], lr + vst1.32 {d1[0]}, [r1], r4 + vadd.u8 d2, d2, d6 + vext.8 d19, d21, d21, #1 + paeth d3, d2, d19, d18 + vst1.32 {d2[0]}, [r1], r4 + vmov d4, d19 + vadd.u8 d3, d3, d7 + vst1.32 {d3[0]}, [r1], r4 + subs r12, r12, #12 + bgt 1b + + pop {r4,pc} +endfunc +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */ +#endif /* READ */ diff --git a/src/thirdparty/libpng/arm/filter_neon_intrinsics.c b/src/thirdparty/libpng/arm/filter_neon_intrinsics.c new file mode 100644 index 000000000..553c0be21 --- /dev/null +++ b/src/thirdparty/libpng/arm/filter_neon_intrinsics.c @@ -0,0 +1,402 @@ + +/* filter_neon_intrinsics.c - NEON optimised filter functions + * + * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2014,2016 Glenn Randers-Pehrson + * Written by James Yu , October 2013. + * Based on filter_neon.S, written by Mans Rullgard, 2011. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* This code requires -mfpu=neon on the command line: */ +#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ + +#if defined(_MSC_VER) && defined(_M_ARM64) +# include +#else +# include +#endif + +/* libpng row pointers are not necessarily aligned to any particular boundary, + * however this code will only work with appropriate alignment. arm/arm_init.c + * checks for this (and will not compile unless it is done). This code uses + * variants of png_aligncast to avoid compiler warnings. + */ +#define png_ptr(type,pointer) png_aligncast(type *,pointer) +#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) + +/* The following relies on a variable 'temp_pointer' being declared with type + * 'type'. This is written this way just to hide the GCC strict aliasing + * warning; note that the code is safe because there never is an alias between + * the input and output pointers. + * + * When compiling with MSVC ARM64, the png_ldr macro can't be passed directly + * to vst4_lane_u32, because of an internal compiler error inside MSVC. + * To avoid this compiler bug, we use a temporary variable (vdest_val) to store + * the result of png_ldr. + */ +#define png_ldr(type,pointer)\ + (temp_pointer = png_ptr(type,pointer), *temp_pointer) + +#if PNG_ARM_NEON_OPT > 0 + +void +png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + png_debug(1, "in png_read_filter_row_up_neon"); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint8x16_t qrp, qpp; + + qrp = vld1q_u8(rp); + qpp = vld1q_u8(pp); + qrp = vaddq_u8(qrp, qpp); + vst1q_u8(rp, qrp); + } +} + +void +png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp = vld1q_u8(rp); + uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); + uint8x8x2_t vrp = *vrpt; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + png_debug(1, "in png_read_filter_row_sub3_neon"); + + for (; rp < rp_stop;) + { + uint8x8_t vtmp1, vtmp2; + uint32x2_t *temp_pointer; + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); + vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); + vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); + + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); + vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t, &vtmp); + vrp = *vrpt; + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } + + PNG_UNUSED(prev_row) +} + +void +png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + png_debug(1, "in png_read_filter_row_sub4_neon"); + + for (; rp < rp_stop; rp += 16) + { + uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); + uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); + uint8x8x4_t vrp = *vrpt; + uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; + + vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); + vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); + vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); + + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); + } + + PNG_UNUSED(prev_row) +} + +void +png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_const_bytep pp = prev_row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp; + uint8x8x2_t *vrpt; + uint8x8x2_t vrp; + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + vtmp = vld1q_u8(rp); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + png_debug(1, "in png_read_filter_row_avg3_neon"); + + for (; rp < rp_stop; pp += 12) + { + uint8x8_t vtmp1, vtmp2, vtmp3; + + uint8x8x2_t *vppt; + uint8x8x2_t vpp; + + uint32x2_t *temp_pointer; + + vtmp = vld1q_u8(pp); + vppt = png_ptr(uint8x8x2_t,&vtmp); + vpp = *vppt; + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); + vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); + vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); + vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); + + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); + vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); + + vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); + + vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); + vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } +} + +void +png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + png_debug(1, "in png_read_filter_row_avg4_neon"); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint32x2x4_t vtmp; + uint8x8x4_t *vrpt, *vppt; + uint8x8x4_t vrp, vpp; + uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; + + vtmp = vld4_u32(png_ptr(uint32_t,rp)); + vrpt = png_ptr(uint8x8x4_t,&vtmp); + vrp = *vrpt; + vtmp = vld4_u32(png_ptrc(uint32_t,pp)); + vppt = png_ptr(uint8x8x4_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); + vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); + vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); + vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); + vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); + vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); + + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); + } +} + +static uint8x8_t +paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) +{ + uint8x8_t d, e; + uint16x8_t p1, pa, pb, pc; + + p1 = vaddl_u8(a, b); /* a + b */ + pc = vaddl_u8(c, c); /* c * 2 */ + pa = vabdl_u8(b, c); /* pa */ + pb = vabdl_u8(a, c); /* pb */ + pc = vabdq_u16(p1, pc); /* pc */ + + p1 = vcleq_u16(pa, pb); /* pa <= pb */ + pa = vcleq_u16(pa, pc); /* pa <= pc */ + pb = vcleq_u16(pb, pc); /* pb <= pc */ + + p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ + + d = vmovn_u16(pb); + e = vmovn_u16(p1); + + d = vbsl_u8(d, b, c); + e = vbsl_u8(e, a, d); + + return e; +} + +void +png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_const_bytep pp = prev_row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp; + uint8x8x2_t *vrpt; + uint8x8x2_t vrp; + uint8x8_t vlast = vdup_n_u8(0); + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + vtmp = vld1q_u8(rp); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + png_debug(1, "in png_read_filter_row_paeth3_neon"); + + for (; rp < rp_stop; pp += 12) + { + uint8x8x2_t *vppt; + uint8x8x2_t vpp; + uint8x8_t vtmp1, vtmp2, vtmp3; + uint32x2_t *temp_pointer; + + vtmp = vld1q_u8(pp); + vppt = png_ptr(uint8x8x2_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); + vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); + vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); + vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); + vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); + + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); + vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); + + vlast = vtmp2; + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } +} + +void +png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + uint8x8_t vlast = vdup_n_u8(0); + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + png_debug(1, "in png_read_filter_row_paeth4_neon"); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint32x2x4_t vtmp; + uint8x8x4_t *vrpt, *vppt; + uint8x8x4_t vrp, vpp; + uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; + + vtmp = vld4_u32(png_ptr(uint32_t,rp)); + vrpt = png_ptr(uint8x8x4_t,&vtmp); + vrp = *vrpt; + vtmp = vld4_u32(png_ptrc(uint32_t,pp)); + vppt = png_ptr(uint8x8x4_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); + vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); + vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); + vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); + vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); + + vlast = vpp.val[3]; + + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); + } +} + +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ +#endif /* READ */ diff --git a/src/thirdparty/libpng/arm/palette_neon_intrinsics.c b/src/thirdparty/libpng/arm/palette_neon_intrinsics.c new file mode 100644 index 000000000..b4d1fd2ab --- /dev/null +++ b/src/thirdparty/libpng/arm/palette_neon_intrinsics.c @@ -0,0 +1,149 @@ + +/* palette_neon_intrinsics.c - NEON optimised palette expansion functions + * + * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2017-2018 Arm Holdings. All rights reserved. + * Written by Richard Townsend , February 2017. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "../pngpriv.h" + +#if PNG_ARM_NEON_IMPLEMENTATION == 1 + +#if defined(_MSC_VER) && defined(_M_ARM64) +# include +#else +# include +#endif + +/* Build an RGBA8 palette from the separate RGB and alpha palettes. */ +void +png_riffle_palette_neon(png_structrp png_ptr) +{ + png_const_colorp palette = png_ptr->palette; + png_bytep riffled_palette = png_ptr->riffled_palette; + png_const_bytep trans_alpha = png_ptr->trans_alpha; + int num_trans = png_ptr->num_trans; + int i; + + png_debug(1, "in png_riffle_palette_neon"); + + /* Initially black, opaque. */ + uint8x16x4_t w = {{ + vdupq_n_u8(0x00), + vdupq_n_u8(0x00), + vdupq_n_u8(0x00), + vdupq_n_u8(0xff), + }}; + + /* First, riffle the RGB colours into an RGBA8 palette. + * The alpha component is set to opaque for now. + */ + for (i = 0; i < 256; i += 16) + { + uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); + w.val[0] = v.val[0]; + w.val[1] = v.val[1]; + w.val[2] = v.val[2]; + vst4q_u8(riffled_palette + (i << 2), w); + } + + /* Fix up the missing transparency values. */ + for (i = 0; i < num_trans; i++) + riffled_palette[(i << 2) + 3] = trans_alpha[i]; +} + +/* Expands a palettized row into RGBA8. */ +int +png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info, + png_const_bytep row, png_bytepp ssp, png_bytepp ddp) +{ + png_uint_32 row_width = row_info->width; + const png_uint_32 *riffled_palette = + (const png_uint_32 *)png_ptr->riffled_palette; + const png_int_32 pixels_per_chunk = 4; + int i; + + png_debug(1, "in png_do_expand_palette_rgba8_neon"); + + if (row_width < pixels_per_chunk) + return 0; + + /* This function originally gets the last byte of the output row. + * The NEON part writes forward from a given position, so we have + * to seek this back by 4 pixels x 4 bytes. + */ + *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1); + + for (i = 0; i < row_width; i += pixels_per_chunk) + { + uint32x4_t cur; + png_bytep sp = *ssp - i, dp = *ddp - (i << 2); + cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); + cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1); + cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2); + cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); + vst1q_u32((void *)dp, cur); + } + if (i != row_width) + { + /* Remove the amount that wasn't processed. */ + i -= pixels_per_chunk; + } + + /* Decrement output pointers. */ + *ssp = *ssp - i; + *ddp = *ddp - (i << 2); + return i; +} + +/* Expands a palettized row into RGB8. */ +int +png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info, + png_const_bytep row, png_bytepp ssp, png_bytepp ddp) +{ + png_uint_32 row_width = row_info->width; + png_const_bytep palette = (png_const_bytep)png_ptr->palette; + const png_uint_32 pixels_per_chunk = 8; + int i; + + png_debug(1, "in png_do_expand_palette_rgb8_neon"); + + if (row_width <= pixels_per_chunk) + return 0; + + /* Seeking this back by 8 pixels x 3 bytes. */ + *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1); + + for (i = 0; i < row_width; i += pixels_per_chunk) + { + uint8x8x3_t cur; + png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i); + cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7))); + cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1); + cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2); + cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3); + cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4); + cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5); + cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6); + cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7); + vst3_u8((void *)dp, cur); + } + + if (i != row_width) + { + /* Remove the amount that wasn't processed. */ + i -= pixels_per_chunk; + } + + /* Decrement output pointers. */ + *ssp = *ssp - i; + *ddp = *ddp - ((i << 1) + i); + return i; +} + +#endif /* PNG_ARM_NEON_IMPLEMENTATION */