From 24e1005a0767900b106b3ca10eba9d722d1798ee 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 | 248 +++++++++++++++++++++++++++++++++++++++++++++ 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, 276 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 28b9d141..ca65ca38 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 00000000..f5988c18 --- /dev/null +++ b/app/src/icon.c @@ -0,0 +1,248 @@ +#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: %s (%d)", desc->name, + 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 00000000..35c8ee43 --- /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 73b29da9..00000000 --- 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 a543e11c..037046df 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 fe2bc867..d2eedd4b 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 feb3d1cb..00000000 --- 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 6e6f8035..00000000 --- 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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 literal 0 HcmV?d00001 diff --git a/release.make b/release.make index 873762b4..b30393d3 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 628c5c7e..fda3ea57 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" "$@"