diff options
-rw-r--r-- | applypatch/imgdiff.cpp | 19 | ||||
-rw-r--r-- | interlace-frames.py | 79 | ||||
-rw-r--r-- | minui/minui.h | 4 | ||||
-rw-r--r-- | minui/resources.cpp | 21 | ||||
-rw-r--r-- | res-hdpi/images/icon_installing.png | bin | 118562 -> 129975 bytes | |||
-rw-r--r-- | res-mdpi/images/icon_installing.png | bin | 118562 -> 129975 bytes | |||
-rw-r--r-- | res-xhdpi/images/icon_installing.png | bin | 118562 -> 129975 bytes | |||
-rw-r--r-- | res-xxhdpi/images/icon_installing.png | bin | 118562 -> 129975 bytes | |||
-rw-r--r-- | res-xxxhdpi/images/icon_installing.png | bin | 118562 -> 129975 bytes | |||
-rw-r--r-- | screen_ui.cpp | 9 | ||||
-rw-r--r-- | screen_ui.h | 4 | ||||
-rw-r--r-- | wear_ui.cpp | 2 | ||||
-rw-r--r-- | wear_ui.h | 5 |
13 files changed, 95 insertions, 48 deletions
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp index 50cabbe6b..f22502e38 100644 --- a/applypatch/imgdiff.cpp +++ b/applypatch/imgdiff.cpp @@ -407,6 +407,7 @@ unsigned char* ReadImage(const char* filename, while (pos < sz) { unsigned char* p = img+pos; + bool processed_deflate = false; if (sz - pos >= 4 && p[0] == 0x1f && p[1] == 0x8b && p[2] == 0x08 && // deflate compression @@ -460,18 +461,24 @@ unsigned char* ReadImage(const char* filename, strm.next_out = curr->data + curr->len; ret = inflate(&strm, Z_NO_FLUSH); if (ret < 0) { - printf("Error: inflate failed [%s] at file offset [%zu]\n" - "imgdiff only supports gzip kernel compression," - " did you try CONFIG_KERNEL_LZO?\n", - strm.msg, chunk_offset); - free(img); - return NULL; + if (!processed_deflate) { + // This is the first chunk, assume that it's just a spurious + // gzip header instead of a real one. + break; + } + printf("Error: inflate failed [%s] at file offset [%zu]\n" + "imgdiff only supports gzip kernel compression," + " did you try CONFIG_KERNEL_LZO?\n", + strm.msg, chunk_offset); + free(img); + return NULL; } curr->len = allocated - strm.avail_out; if (strm.avail_out == 0) { allocated *= 2; curr->data = reinterpret_cast<unsigned char*>(realloc(curr->data, allocated)); } + processed_deflate = true; } while (ret != Z_STREAM_END); curr->deflate_len = sz - strm.avail_in - pos; diff --git a/interlace-frames.py b/interlace-frames.py index 243e565e7..3e777b470 100644 --- a/interlace-frames.py +++ b/interlace-frames.py @@ -12,42 +12,69 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Script to take a set of frames (PNG files) for a recovery animation -and turn it into a single output image which contains the input frames -interlaced by row. Run with the names of all the input frames on the -command line, in order, followed by the name of the output file.""" +""" +Script to take a set of frames (PNG files) for a recovery animation and turn +it into a single output image which contains the input frames interlaced by +row. Run with the names of all the input frames on the command line. Specify +the name of the output file with -o (or --output), and optionally specify the +number of frames per second (FPS) with --fps (default: 20). +e.g. +interlace-frames.py --fps 20 --output output.png frame0.png frame1.png frame3.png +""" + +from __future__ import print_function + +import argparse import sys try: import Image import PngImagePlugin except ImportError: - print "This script requires the Python Imaging Library to be installed." + print("This script requires the Python Imaging Library to be installed.") sys.exit(1) -frames = [Image.open(fn).convert("RGB") for fn in sys.argv[1:-1]] -assert len(frames) > 0, "Must have at least one input frame." -sizes = set() -for fr in frames: - sizes.add(fr.size) -assert len(sizes) == 1, "All input images must have the same size." -w, h = sizes.pop() -N = len(frames) +def interlace(output, fps, inputs): + frames = [Image.open(fn).convert("RGB") for fn in inputs] + assert len(frames) > 0, "Must have at least one input frame." + sizes = set() + for fr in frames: + sizes.add(fr.size) + + assert len(sizes) == 1, "All input images must have the same size." + w, h = sizes.pop() + N = len(frames) + + out = Image.new("RGB", (w, h*N)) + for j in range(h): + for i in range(w): + for fn, f in enumerate(frames): + out.putpixel((i, j*N+fn), f.getpixel((i, j))) + + # When loading this image, the graphics library expects to find a text + # chunk that specifies how many frames this animation represents. If + # you post-process the output of this script with some kind of + # optimizer tool (eg pngcrush or zopflipng) make sure that your + # optimizer preserves this text chunk. + + meta = PngImagePlugin.PngInfo() + meta.add_text("Frames", str(N)) + meta.add_text("FPS", str(fps)) + + out.save(output, pnginfo=meta) + + +def main(argv): + parser = argparse.ArgumentParser() + parser.add_argument('--fps', default=20) + parser.add_argument('--output', '-o', required=True) + parser.add_argument('input', nargs='+') + args = parser.parse_args(argv) -out = Image.new("RGB", (w, h*N)) -for j in range(h): - for i in range(w): - for fn, f in enumerate(frames): - out.putpixel((i, j*N+fn), f.getpixel((i, j))) + interlace(args.output, args.fps, args.input) -# When loading this image, the graphics library expects to find a text -# chunk that specifies how many frames this animation represents. If -# you post-process the output of this script with some kind of -# optimizer tool (eg pngcrush or zopflipng) make sure that your -# optimizer preserves this text chunk. -meta = PngImagePlugin.PngInfo() -meta.add_text("Frames", str(N)) +if __name__ == '__main__': + main(sys.argv[1:]) -out.save(sys.argv[-1], pnginfo=meta) diff --git a/minui/minui.h b/minui/minui.h index bdde083f3..e3bc00548 100644 --- a/minui/minui.h +++ b/minui/minui.h @@ -101,8 +101,8 @@ int res_create_display_surface(const char* name, GRSurface** pSurface); // should have a 'Frames' text chunk whose value is the number of // frames this image represents. The pixel data itself is interlaced // by row. -int res_create_multi_display_surface(const char* name, - int* frames, GRSurface*** pSurface); +int res_create_multi_display_surface(const char* name, int* frames, + int* fps, GRSurface*** pSurface); // Load a single alpha surface from a grayscale PNG image. int res_create_alpha_surface(const char* name, GRSurface** pSurface); diff --git a/minui/resources.cpp b/minui/resources.cpp index 5e4789277..63a0dff28 100644 --- a/minui/resources.cpp +++ b/minui/resources.cpp @@ -237,14 +237,14 @@ int res_create_display_surface(const char* name, GRSurface** pSurface) { return result; } -int res_create_multi_display_surface(const char* name, int* frames, GRSurface*** pSurface) { +int res_create_multi_display_surface(const char* name, int* frames, int* fps, + GRSurface*** pSurface) { GRSurface** surface = NULL; int result = 0; png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_uint_32 width, height; png_byte channels; - int i; png_textp text; int num_text; unsigned char* p_row; @@ -257,14 +257,23 @@ int res_create_multi_display_surface(const char* name, int* frames, GRSurface*** if (result < 0) return result; *frames = 1; + *fps = 20; if (png_get_text(png_ptr, info_ptr, &text, &num_text)) { - for (i = 0; i < num_text; ++i) { + for (int i = 0; i < num_text; ++i) { if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) { *frames = atoi(text[i].text); - break; + } else if (text[i].key && strcmp(text[i].key, "FPS") == 0 && text[i].text) { + *fps = atoi(text[i].text); } } printf(" found frames = %d\n", *frames); + printf(" found fps = %d\n", *fps); + } + + if (frames <= 0 || fps <= 0) { + printf("bad number of frames (%d) and/or FPS (%d)\n", *frames, *fps); + result = -10; + goto exit; } if (height % *frames != 0) { @@ -278,7 +287,7 @@ int res_create_multi_display_surface(const char* name, int* frames, GRSurface*** result = -8; goto exit; } - for (i = 0; i < *frames; ++i) { + for (int i = 0; i < *frames; ++i) { surface[i] = init_display_surface(width, height / *frames); if (surface[i] == NULL) { result = -8; @@ -307,7 +316,7 @@ exit: if (result < 0) { if (surface) { - for (i = 0; i < *frames; ++i) { + for (int i = 0; i < *frames; ++i) { if (surface[i]) free(surface[i]); } free(surface); diff --git a/res-hdpi/images/icon_installing.png b/res-hdpi/images/icon_installing.png Binary files differindex c2c020162..0fcfbc231 100644 --- a/res-hdpi/images/icon_installing.png +++ b/res-hdpi/images/icon_installing.png diff --git a/res-mdpi/images/icon_installing.png b/res-mdpi/images/icon_installing.png Binary files differindex c2c020162..0fcfbc231 100644 --- a/res-mdpi/images/icon_installing.png +++ b/res-mdpi/images/icon_installing.png diff --git a/res-xhdpi/images/icon_installing.png b/res-xhdpi/images/icon_installing.png Binary files differindex c2c020162..0fcfbc231 100644 --- a/res-xhdpi/images/icon_installing.png +++ b/res-xhdpi/images/icon_installing.png diff --git a/res-xxhdpi/images/icon_installing.png b/res-xxhdpi/images/icon_installing.png Binary files differindex c2c020162..0fcfbc231 100644 --- a/res-xxhdpi/images/icon_installing.png +++ b/res-xxhdpi/images/icon_installing.png diff --git a/res-xxxhdpi/images/icon_installing.png b/res-xxxhdpi/images/icon_installing.png Binary files differindex c2c020162..0fcfbc231 100644 --- a/res-xxxhdpi/images/icon_installing.png +++ b/res-xxxhdpi/images/icon_installing.png diff --git a/screen_ui.cpp b/screen_ui.cpp index 23fc90154..522aa6b23 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -73,7 +73,7 @@ ScreenRecoveryUI::ScreenRecoveryUI() : menu_items(0), menu_sel(0), file_viewer_text_(nullptr), - animation_fps(20), + animation_fps(-1), installing_frames(-1), stage(-1), max_stage(-1) { @@ -367,8 +367,9 @@ void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) { } } -void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, GRSurface*** surface) { - int result = res_create_multi_display_surface(filename, frames, surface); +void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, int* fps, + GRSurface*** surface) { + int result = res_create_multi_display_surface(filename, frames, fps, surface); if (result < 0) { LOGE("missing bitmap %s\n(Code %d)\n", filename, result); } @@ -405,7 +406,7 @@ void ScreenRecoveryUI::Init() { text_top_ = 1; backgroundIcon[NONE] = nullptr; - LoadBitmapArray("icon_installing", &installing_frames, &installation); + LoadBitmapArray("icon_installing", &installing_frames, &animation_fps, &installation); backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : nullptr; backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; LoadBitmap("icon_error", &backgroundIcon[ERROR]); diff --git a/screen_ui.h b/screen_ui.h index 8e18864d7..08a5f44a9 100644 --- a/screen_ui.h +++ b/screen_ui.h @@ -109,6 +109,8 @@ class ScreenRecoveryUI : public RecoveryUI { pthread_t progress_thread_; + // The following two are parsed from the image file + // (e.g. '/res/images/icon_installing.png'). int animation_fps; int installing_frames; @@ -135,7 +137,7 @@ class ScreenRecoveryUI : public RecoveryUI { void DrawTextLines(int* y, const char* const* lines); void LoadBitmap(const char* filename, GRSurface** surface); - void LoadBitmapArray(const char* filename, int* frames, GRSurface*** surface); + void LoadBitmapArray(const char* filename, int* frames, int* fps, GRSurface*** surface); void LoadLocalizedBitmap(const char* filename, GRSurface** surface); }; diff --git a/wear_ui.cpp b/wear_ui.cpp index 3ee38e8a4..50aeb3849 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -61,10 +61,10 @@ WearRecoveryUI::WearRecoveryUI() : menu_unusable_rows(0), intro_frames(22), loop_frames(60), + animation_fps(30), currentIcon(NONE), intro_done(false), current_frame(0), - animation_fps(30), rtl_locale(false), progressBarType(EMPTY), progressScopeStart(0), @@ -79,6 +79,9 @@ class WearRecoveryUI : public RecoveryUI { int intro_frames; int loop_frames; + // Number of frames per sec (default: 30) for both of intro and loop. + int animation_fps; + private: Icon currentIcon; @@ -86,8 +89,6 @@ class WearRecoveryUI : public RecoveryUI { int current_frame; - int animation_fps; - bool rtl_locale; pthread_mutex_t updateMutex; |