From 4aa4f8de68b983cf2368bde474d4960895867c60 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 20 Dec 2020 15:16:02 +0100 Subject: [PATCH] [WIP] icon --- app/meson.build | 5 +- app/src/icon.c | 247 +++++++++++++++++++++++++++++++++++++++++++++ app/src/icon.h | 16 +++ app/src/icon.xpm | 53 ---------- app/src/scrcpy.c | 1 - app/src/screen.c | 7 +- app/src/tiny_xpm.c | 120 ---------------------- app/src/tiny_xpm.h | 11 -- data/icon.png | Bin 0 -> 6540 bytes release.make | 2 + run | 4 +- 11 files changed, 275 insertions(+), 191 deletions(-) create mode 100644 app/src/icon.c create mode 100644 app/src/icon.h delete mode 100644 app/src/icon.xpm delete mode 100644 app/src/tiny_xpm.c delete mode 100644 app/src/tiny_xpm.h create mode 100644 data/icon.png diff --git a/app/meson.build b/app/meson.build index 28b9d14186..ca65ca3855 100644 --- a/app/meson.build +++ b/app/meson.build @@ -8,6 +8,7 @@ src = [ 'src/device.c', 'src/device_msg.c', 'src/event_converter.c', + 'src/icon.c', 'src/file_handler.c', 'src/fps_counter.c', 'src/input_manager.c', @@ -18,7 +19,6 @@ src = [ 'src/screen.c', 'src/server.c', 'src/stream.c', - 'src/tiny_xpm.c', 'src/video_buffer.c', 'src/util/net.c', 'src/util/str_util.c' @@ -136,6 +136,9 @@ executable('scrcpy', src, c_args: []) install_man('scrcpy.1') +install_data('../data/icon.png', + rename: 'scrcpy.png', + install_dir: 'share/icons/hicolor/512x512/apps') ### TESTS diff --git a/app/src/icon.c b/app/src/icon.c new file mode 100644 index 0000000000..81c97be745 --- /dev/null +++ b/app/src/icon.c @@ -0,0 +1,247 @@ +#include "icon.h" + +#include +#include +#include +#include +#include + +#include "config.h" +#include "command.h" +#include "compat.h" +#include "util/log.h" +#include "util/str_util.h" + +#define SCRCPY_PORTABLE_ICON_FILENAME "icon.png" +#define SCRCPY_DEFAULT_ICON_PATH PREFIX \ + "/share/icons/hicolor/512x512/apps/scrcpy.png" + +static char * +get_icon_path(void) { +#ifdef __WINDOWS__ + const wchar_t *icon_path_env = _wgetenv(L"SCRCPY_ICON_PATH"); +#else + const char *icon_path_env = getenv("SCRCPY_ICON_PATH"); +#endif + if (icon_path_env) { + // if the envvar is set, use it +#ifdef __WINDOWS__ + char *icon_path = utf8_from_wide_char(icon_path_env); +#else + char *icon_path = SDL_strdup(icon_path_env); +#endif + if (!icon_path) { + LOGE("Could not allocate memory"); + return NULL; + } + LOGD("Using SCRCPY_ICON_PATH: %s", icon_path); + return icon_path; + } + +#ifndef PORTABLE + char *icon_path = SDL_strdup(SCRCPY_DEFAULT_ICON_PATH); + if (!icon_path) { + LOGE("Could not allocate memory"); + return NULL; + } +#else + char *icon_path = get_local_file_path(SCRCPY_PORTABLE_ICON_FILENAME); + if (!icon_path) { + LOGE("Could not get icon path"); + return NULL; + } +#endif + + return icon_path; +} + +static AVFrame * +decode_image(const char *path) { + AVFrame *result = NULL; + + AVFormatContext *ctx = avformat_alloc_context(); + if (!ctx) { + LOGE("Could not allocate image decoder context"); + return NULL; + } + + if (avformat_open_input(&ctx, path, NULL, NULL) < 0) { + LOGE("Could not open image codec"); + goto free_ctx; + } + + if (avformat_find_stream_info(ctx, NULL) < 0) { + LOGE("Could not find image stream info"); + goto close_input; + } + + int stream = av_find_best_stream(ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); + if (stream < 0 ) { + LOGE("Could not find best image stream"); + goto close_input; + } + +#ifdef SCRCPY_LAVF_HAS_NEW_CODEC_PARAMS_API + AVCodecParameters *params = ctx->streams[stream]->codecpar; + + AVCodec *codec = avcodec_find_decoder(params->codec_id); + if (!codec) { + LOGE("Could not find image decoder"); + goto close_input; + } + + AVCodecContext *codec_ctx = avcodec_alloc_context3(codec); + if (avcodec_parameters_to_context(codec_ctx, params) < 0) { + LOGE("Could not fill codec context"); + goto free_codec_ctx; + } +#else + AVCodecContext *codec_ctx = ctx->streams[stream]->codec; + + AVCodec *codec = avcodec_find_decoder(codec_ctx->codec_id); + if (!codec) { + LOGE("Could not find image decoder"); + goto close_input; + } +#endif + + if (avcodec_open2(codec_ctx, codec, NULL) < 0) { + LOGE("Could not open image codec"); + goto free_codec_ctx; + } + + AVFrame *frame = av_frame_alloc(); + if (!frame) { + LOGE("Could not allocate frame"); + goto close_codec; + } + + AVPacket packet; + av_init_packet(&packet); + + if (av_read_frame(ctx, &packet) < 0) { + LOGE("Could not read frame"); + av_frame_free(&frame); + goto close_input; + } + +#ifdef SCRCPY_LAVF_HAS_NEW_ENCODING_DECODING_API + int ret; + if ((ret = avcodec_send_packet(codec_ctx, &packet)) < 0) { + LOGE("Could not send icon packet: %d", ret); + av_frame_free(&frame); + goto close_input; + } + + if ((ret = avcodec_receive_frame(codec_ctx, frame)) != 0) { + LOGE("Could not receive icon frame: %d", ret); + av_frame_free(&frame); + goto close_input; + } + +#else + int got_picture; + int len = avcodec_decode_video2(codec_ctx, frame, &got_picture, &packet); + if (len < 0 || !got_picture) { + LOGE("Could not decode icon: %d", len); + av_frame_free(&frame); + goto close_input; + } +#endif + + av_packet_unref(&packet); + + result = frame; + +close_codec: + avcodec_close(codec_ctx); +free_codec_ctx: +#ifdef SCRCPY_LAVF_HAS_NEW_CODEC_PARAMS_API + avcodec_free_context(&codec_ctx); +#endif +close_input: + avformat_close_input(&ctx); +free_ctx: + avformat_free_context(ctx); + + return result; +} + +static SDL_PixelFormatEnum +to_sdl_pixel_format(enum AVPixelFormat fmt) { + switch (fmt) { + case AV_PIX_FMT_RGB24: return SDL_PIXELFORMAT_RGB24; + case AV_PIX_FMT_BGR24: return SDL_PIXELFORMAT_BGR24; + case AV_PIX_FMT_ARGB: return SDL_PIXELFORMAT_ARGB32; + case AV_PIX_FMT_RGBA: return SDL_PIXELFORMAT_RGBA32; + case AV_PIX_FMT_ABGR: return SDL_PIXELFORMAT_ABGR32; + case AV_PIX_FMT_BGRA: return SDL_PIXELFORMAT_BGRA32; + case AV_PIX_FMT_RGB565BE: return SDL_PIXELFORMAT_RGB565; + case AV_PIX_FMT_RGB555BE: return SDL_PIXELFORMAT_RGB555; + case AV_PIX_FMT_BGR565BE: return SDL_PIXELFORMAT_BGR565; + case AV_PIX_FMT_BGR555BE: return SDL_PIXELFORMAT_BGR555; + case AV_PIX_FMT_RGB444BE: return SDL_PIXELFORMAT_RGB444; + case AV_PIX_FMT_BGR444BE: return SDL_PIXELFORMAT_BGR444; + default: return SDL_PIXELFORMAT_UNKNOWN; + } +} + +SDL_Surface * +scrcpy_icon_load() { + char *icon_path = get_icon_path(); + assert(icon_path); + + AVFrame *frame = decode_image(icon_path); + SDL_free(icon_path); + if (!frame) { + return NULL; + } + + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + if (!desc) { + LOGE("Could not get icon format descriptor"); + goto error; + } + + bool is_packed_rgb = desc->flags & AV_PIX_FMT_FLAG_RGB + && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR); + if (!is_packed_rgb) { + LOGE("Could not load non-RGB icon"); + goto error; + } + + SDL_PixelFormatEnum format = to_sdl_pixel_format(frame->format); + if (format == SDL_PIXELFORMAT_UNKNOWN) { + LOGE("Unsupported icon pixel format: %d", frame->format); + goto error; + } + + int bits_per_pixel = av_get_bits_per_pixel(desc); + SDL_Surface *surface = + SDL_CreateRGBSurfaceWithFormatFrom(frame->data[0], + frame->width, frame->height, + bits_per_pixel, + frame->linesize[0], + format); + + if (!surface) { + LOGE("Could not create icon surface"); + goto error; + } + + surface->userdata = frame; // frame owns the data + + return surface; + +error: + av_frame_free(&frame); + return NULL; +} + +void +scrcpy_icon_destroy(SDL_Surface *icon) { + AVFrame *frame = icon->userdata; + assert(frame); + av_frame_free(&frame); + SDL_FreeSurface(icon); +} diff --git a/app/src/icon.h b/app/src/icon.h new file mode 100644 index 0000000000..35c8ee43d0 --- /dev/null +++ b/app/src/icon.h @@ -0,0 +1,16 @@ +#ifndef ICON_H +#define ICON_H + +#include +#include +#include + +#include "config.h" + +SDL_Surface * +scrcpy_icon_load(void); + +void +scrcpy_icon_destroy(SDL_Surface *icon); + +#endif diff --git a/app/src/icon.xpm b/app/src/icon.xpm deleted file mode 100644 index 73b29da96a..0000000000 --- a/app/src/icon.xpm +++ /dev/null @@ -1,53 +0,0 @@ -/* XPM */ -static char * icon_xpm[] = { -"48 48 2 1", -" c None", -". c #96C13E", -" .. .. ", -" ... ... ", -" ... ...... ... ", -" ................ ", -" .............. ", -" ................ ", -" .................. ", -" .................... ", -" ..... ........ ..... ", -" ..... ........ ..... ", -" ...................... ", -" ........................ ", -" ........................ ", -" ........................ ", -" ", -" ", -" .... ........................ .... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" ...... ........................ ...... ", -" .... ........................ .... ", -" ........................ ", -" ...................... ", -" ...... ...... ", -" ...... ...... ", -" ...... ...... ", -" ...... ...... ", -" ...... ...... ", -" ...... ...... ", -" ...... ...... ", -" ...... ...... ", -" ...... ...... ", -" .... .... "}; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index a543e11c77..037046df8a 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -28,7 +28,6 @@ #include "screen.h" #include "server.h" #include "stream.h" -#include "tiny_xpm.h" #include "video_buffer.h" #include "util/lock.h" #include "util/log.h" diff --git a/app/src/screen.c b/app/src/screen.c index fe2bc867df..d2eedd4b71 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -7,9 +7,8 @@ #include "config.h" #include "common.h" #include "compat.h" -#include "icon.xpm" +#include "icon.h" #include "scrcpy.h" -#include "tiny_xpm.h" #include "video_buffer.h" #include "util/lock.h" #include "util/log.h" @@ -309,10 +308,10 @@ screen_init_rendering(struct screen *screen, const char *window_title, LOGD("Trilinear filtering disabled (not an OpenGL renderer)"); } - SDL_Surface *icon = read_xpm(icon_xpm); + SDL_Surface *icon = scrcpy_icon_load(); if (icon) { SDL_SetWindowIcon(screen->window, icon); - SDL_FreeSurface(icon); + scrcpy_icon_destroy(icon); } else { LOGW("Could not load icon"); } diff --git a/app/src/tiny_xpm.c b/app/src/tiny_xpm.c deleted file mode 100644 index feb3d1cb49..0000000000 --- a/app/src/tiny_xpm.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "tiny_xpm.h" - -#include -#include -#include -#include -#include - -#include "config.h" -#include "util/log.h" - -struct index { - char c; - uint32_t color; -}; - -static bool -find_color(struct index *index, int len, char c, uint32_t *color) { - // there are typically very few color, so it's ok to iterate over the array - for (int i = 0; i < len; ++i) { - if (index[i].c == c) { - *color = index[i].color; - return true; - } - } - *color = 0; - return false; -} - -// We encounter some problems with SDL2_image on MSYS2 (Windows), -// so here is our own XPM parsing not to depend on SDL_image. -// -// We do not hardcode the binary image to keep some flexibility to replace the -// icon easily (just by replacing icon.xpm). -// -// Parameter is not "const char *" because XPM formats are generally stored in a -// (non-const) "char *" -SDL_Surface * -read_xpm(char *xpm[]) { -#ifndef NDEBUG - // patch the XPM to change the icon color in debug mode - xpm[2] = ". c #CC00CC"; -#endif - - char *endptr; - // *** No error handling, assume the XPM source is valid *** - // (it's in our source repo) - // Assertions are only checked in debug - int width = strtol(xpm[0], &endptr, 10); - int height = strtol(endptr + 1, &endptr, 10); - int colors = strtol(endptr + 1, &endptr, 10); - int chars = strtol(endptr + 1, &endptr, 10); - - // sanity checks - assert(0 <= width && width < 256); - assert(0 <= height && height < 256); - assert(0 <= colors && colors < 256); - assert(chars == 1); // this implementation does not support more - - (void) chars; - - // init index - struct index index[colors]; - for (int i = 0; i < colors; ++i) { - const char *line = xpm[1+i]; - index[i].c = line[0]; - assert(line[1] == '\t'); - assert(line[2] == 'c'); - assert(line[3] == ' '); - if (line[4] == '#') { - index[i].color = 0xff000000 | strtol(&line[5], &endptr, 0x10); - assert(*endptr == '\0'); - } else { - assert(!strcmp("None", &line[4])); - index[i].color = 0; - } - } - - // parse image - uint32_t *pixels = SDL_malloc(4 * width * height); - if (!pixels) { - LOGE("Could not allocate icon memory"); - return NULL; - } - for (int y = 0; y < height; ++y) { - const char *line = xpm[1 + colors + y]; - for (int x = 0; x < width; ++x) { - char c = line[x]; - uint32_t color; - bool color_found = find_color(index, colors, c, &color); - assert(color_found); - (void) color_found; - pixels[y * width + x] = color; - } - } - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - uint32_t amask = 0x000000ff; - uint32_t rmask = 0x0000ff00; - uint32_t gmask = 0x00ff0000; - uint32_t bmask = 0xff000000; -#else // little endian, like x86 - uint32_t amask = 0xff000000; - uint32_t rmask = 0x00ff0000; - uint32_t gmask = 0x0000ff00; - uint32_t bmask = 0x000000ff; -#endif - - SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(pixels, - width, height, - 32, 4 * width, - rmask, gmask, bmask, amask); - if (!surface) { - LOGE("Could not create icon surface"); - return NULL; - } - // make the surface own the raw pixels - surface->flags &= ~SDL_PREALLOC; - return surface; -} diff --git a/app/src/tiny_xpm.h b/app/src/tiny_xpm.h deleted file mode 100644 index 6e6f80353d..0000000000 --- a/app/src/tiny_xpm.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef TINYXPM_H -#define TINYXPM_H - -#include - -#include "config.h" - -SDL_Surface * -read_xpm(char *xpm[]); - -#endif diff --git a/data/icon.png b/data/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..06617be8a5496c8dc141dfaa898130275aa42918 GIT binary patch literal 6540 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 XSXn;^Pdjb~pvUZ_^@&Oo&-niVXicov literal 0 HcmV?d00001 diff --git a/release.make b/release.make index 873762b457..b30393d323 100644 --- a/release.make +++ b/release.make @@ -94,6 +94,7 @@ dist-win32: build-server build-win32 cp "$(WIN32_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN32_TARGET_DIR)/" cp data/scrcpy-console.bat "$(DIST)/$(WIN32_TARGET_DIR)" cp data/scrcpy-noconsole.vbs "$(DIST)/$(WIN32_TARGET_DIR)" + cp data/icon.png "$(DIST)/$(WIN32_TARGET_DIR)" cp prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avutil-56.dll "$(DIST)/$(WIN32_TARGET_DIR)/" cp prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avcodec-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/" cp prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avformat-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/" @@ -110,6 +111,7 @@ dist-win64: build-server build-win64 cp "$(WIN64_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN64_TARGET_DIR)/" cp data/scrcpy-console.bat "$(DIST)/$(WIN64_TARGET_DIR)" cp data/scrcpy-noconsole.vbs "$(DIST)/$(WIN64_TARGET_DIR)" + cp data/icon.png "$(DIST)/$(WIN64_TARGET_DIR)" cp prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avutil-56.dll "$(DIST)/$(WIN64_TARGET_DIR)/" cp prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avcodec-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/" cp prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avformat-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/" diff --git a/run b/run index 628c5c7ea6..fda3ea57a1 100755 --- a/run +++ b/run @@ -20,4 +20,6 @@ then exit 1 fi -SCRCPY_SERVER_PATH="$BUILDDIR/server/scrcpy-server" "$BUILDDIR/app/scrcpy" "$@" +SCRCPY_ICON_PATH="data/icon.png" \ +SCRCPY_SERVER_PATH="$BUILDDIR/server/scrcpy-server" \ +"$BUILDDIR/app/scrcpy" "$@"