aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-03-13 09:58:52 +0800
committerPo Lu2023-03-13 09:58:52 +0800
commitc3524b15aa77b309f325fcb806fe9e9c91c4e99e (patch)
tree2498b189ef6a68d1969e97dcd44097056d5bf74d /src
parenta517c24697d080475e2d531c8ce1d433aa44a9c6 (diff)
downloademacs-c3524b15aa77b309f325fcb806fe9e9c91c4e99e.tar.gz
emacs-c3524b15aa77b309f325fcb806fe9e9c91c4e99e.zip
Update Android port
* src/image.c (image_create_bitmap_from_file, image_find_image_fd) (close_android_fd, slurp_file): Return and use `struct android_fd_or_asset' on Android. (xbm_load, xpm_load, pbm_load, png_load_body, jpeg_load_body) (webp_load, svg_load): Adjust accordingly.
Diffstat (limited to 'src')
-rw-r--r--src/image.c107
1 files changed, 91 insertions, 16 deletions
diff --git a/src/image.c b/src/image.c
index a244b23ecd2..dc45a2d2419 100644
--- a/src/image.c
+++ b/src/image.c
@@ -652,9 +652,19 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
652 return id; 652 return id;
653} 653}
654 654
655#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
656#include "android.h"
657
658/* This abstraction allows directly loading images from assets without
659 copying them to a file descriptor first. */
660typedef struct android_fd_or_asset image_fd;
661#else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
662typedef int image_fd;
663#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
664
655#if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_ANDROID 665#if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_ANDROID
656static char *slurp_file (int, ptrdiff_t *); 666static char *slurp_file (image_fd, ptrdiff_t *);
657static Lisp_Object image_find_image_fd (Lisp_Object, int *); 667static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *);
658static bool xbm_read_bitmap_data (struct frame *, char *, char *, 668static bool xbm_read_bitmap_data (struct frame *, char *, char *,
659 int *, int *, char **, bool); 669 int *, int *, char **, bool);
660#endif 670#endif
@@ -877,7 +887,8 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
877 emacs_abort (); 887 emacs_abort ();
878#else 888#else
879 ptrdiff_t id, size; 889 ptrdiff_t id, size;
880 int fd, width, height, rc; 890 int width, height, rc;
891 image_fd fd;
881 char *contents, *data; 892 char *contents, *data;
882 Lisp_Object found; 893 Lisp_Object found;
883 android_pixmap bitmap; 894 android_pixmap bitmap;
@@ -4135,10 +4146,11 @@ image_unget_x_image (struct image *img, bool mask_p, Emacs_Pix_Container ximg)
4135 PFD is null, do not open the file. */ 4146 PFD is null, do not open the file. */
4136 4147
4137static Lisp_Object 4148static Lisp_Object
4138image_find_image_fd (Lisp_Object file, int *pfd) 4149image_find_image_fd (Lisp_Object file, image_fd *pfd)
4139{ 4150{
4140 Lisp_Object file_found, search_path; 4151 Lisp_Object file_found, search_path;
4141 int fd; 4152 int fd;
4153 void *platform;
4142 4154
4143 /* TODO I think this should use something like image-load-path 4155 /* TODO I think this should use something like image-load-path
4144 instead. Unfortunately, that can contain non-string elements. */ 4156 instead. Unfortunately, that can contain non-string elements. */
@@ -4147,9 +4159,10 @@ image_find_image_fd (Lisp_Object file, int *pfd)
4147 Vx_bitmap_file_path); 4159 Vx_bitmap_file_path);
4148 4160
4149 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */ 4161 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
4162 platform = NULL;
4150 fd = openp (search_path, file, Qnil, &file_found, 4163 fd = openp (search_path, file, Qnil, &file_found,
4151 pfd ? Qt : make_fixnum (R_OK), false, false, 4164 pfd ? Qt : make_fixnum (R_OK), false, false,
4152 NULL); 4165 pfd ? &platform : NULL);
4153 if (fd == -2) 4166 if (fd == -2)
4154 { 4167 {
4155 /* The file exists locally, but has a file name handler. 4168 /* The file exists locally, but has a file name handler.
@@ -4159,10 +4172,23 @@ image_find_image_fd (Lisp_Object file, int *pfd)
4159 Lisp_Object encoded_name = ENCODE_FILE (file_found); 4172 Lisp_Object encoded_name = ENCODE_FILE (file_found);
4160 fd = emacs_open (SSDATA (encoded_name), O_RDONLY, 0); 4173 fd = emacs_open (SSDATA (encoded_name), O_RDONLY, 0);
4161 } 4174 }
4162 else if (fd < 0) 4175 /* FD is -3 if PLATFORM is set to a valid asset file descriptor on
4176 Android. */
4177 else if (fd < 0 && fd != -3)
4163 return Qnil; 4178 return Qnil;
4179
4180#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
4164 if (pfd) 4181 if (pfd)
4165 *pfd = fd; 4182 *pfd = fd;
4183#else
4184 /* Construct an asset file descriptor. */
4185
4186 if (pfd)
4187 {
4188 pfd->fd = fd;
4189 pfd->asset = platform;
4190 }
4191#endif
4166 return file_found; 4192 return file_found;
4167} 4193}
4168 4194
@@ -4176,14 +4202,25 @@ image_find_image_file (Lisp_Object file)
4176 return image_find_image_fd (file, 0); 4202 return image_find_image_fd (file, 0);
4177} 4203}
4178 4204
4205#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
4206
4207static void
4208close_android_fd (void *ptr)
4209{
4210 android_close_asset (*(struct android_fd_or_asset *) ptr);
4211}
4212
4213#endif
4214
4179/* Read FILE into memory. Value is a pointer to a buffer allocated 4215/* Read FILE into memory. Value is a pointer to a buffer allocated
4180 with xmalloc holding FILE's contents. Value is null if an error 4216 with xmalloc holding FILE's contents. Value is null if an error
4181 occurred. FD is a file descriptor open for reading FILE. Set 4217 occurred. FD is a file descriptor open for reading FILE. Set
4182 *SIZE to the size of the file. */ 4218 *SIZE to the size of the file. */
4183 4219
4184static char * 4220static char *
4185slurp_file (int fd, ptrdiff_t *size) 4221slurp_file (image_fd fd, ptrdiff_t *size)
4186{ 4222{
4223#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
4187 FILE *fp = fdopen (fd, "rb"); 4224 FILE *fp = fdopen (fd, "rb");
4188 4225
4189 char *buf = NULL; 4226 char *buf = NULL;
@@ -4212,6 +4249,39 @@ slurp_file (int fd, ptrdiff_t *size)
4212 4249
4213 unbind_to (count, Qnil); 4250 unbind_to (count, Qnil);
4214 } 4251 }
4252#else
4253 char *buf;
4254 struct stat st;
4255 specpdl_ref count;
4256
4257 if (!android_asset_fstat (fd, &st)
4258 && (0 <= st.st_size
4259 && st.st_size < min (PTRDIFF_MAX, SIZE_MAX)))
4260 {
4261 count = SPECPDL_INDEX ();
4262 record_unwind_protect_ptr (close_android_fd, &fd);
4263 buf = xmalloc (st.st_size + 1);
4264
4265 /* Read one byte past the end of the file. That allows
4266 detecting if the file grows as it is being read. */
4267
4268 if (android_asset_read (fd, buf,
4269 st.st_size + 1) == st.st_size)
4270 *size = st.st_size;
4271 else
4272 {
4273 xfree (buf);
4274 buf = NULL;
4275 }
4276
4277 unbind_to (count, Qnil);
4278 }
4279 else
4280 {
4281 buf = NULL;
4282 android_close_asset (fd);
4283 }
4284#endif
4215 4285
4216 return buf; 4286 return buf;
4217} 4287}
@@ -4934,7 +5004,7 @@ xbm_load (struct frame *f, struct image *img)
4934 file_name = image_spec_value (img->spec, QCfile, NULL); 5004 file_name = image_spec_value (img->spec, QCfile, NULL);
4935 if (STRINGP (file_name)) 5005 if (STRINGP (file_name))
4936 { 5006 {
4937 int fd; 5007 image_fd fd;
4938 Lisp_Object file = image_find_image_fd (file_name, &fd); 5008 Lisp_Object file = image_find_image_fd (file_name, &fd);
4939 if (!STRINGP (file)) 5009 if (!STRINGP (file))
4940 { 5010 {
@@ -6230,7 +6300,7 @@ xpm_load (struct frame *f,
6230 file_name = image_spec_value (img->spec, QCfile, NULL); 6300 file_name = image_spec_value (img->spec, QCfile, NULL);
6231 if (STRINGP (file_name)) 6301 if (STRINGP (file_name))
6232 { 6302 {
6233 int fd; 6303 image_fd fd;
6234 Lisp_Object file = image_find_image_fd (file_name, &fd); 6304 Lisp_Object file = image_find_image_fd (file_name, &fd);
6235 if (!STRINGP (file)) 6305 if (!STRINGP (file))
6236 { 6306 {
@@ -7259,7 +7329,7 @@ pbm_load (struct frame *f, struct image *img)
7259 7329
7260 if (STRINGP (specified_file)) 7330 if (STRINGP (specified_file))
7261 { 7331 {
7262 int fd; 7332 image_fd fd;
7263 Lisp_Object file = image_find_image_fd (specified_file, &fd); 7333 Lisp_Object file = image_find_image_fd (specified_file, &fd);
7264 if (!STRINGP (file)) 7334 if (!STRINGP (file))
7265 { 7335 {
@@ -7927,8 +7997,11 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
7927 if (NILP (specified_data)) 7997 if (NILP (specified_data))
7928 { 7998 {
7929 int fd; 7999 int fd;
7930 Lisp_Object file = image_find_image_fd (specified_file, &fd); 8000 Lisp_Object file = image_find_image_file (specified_file);
7931 if (!STRINGP (file)) 8001
8002 if (!STRINGP (file)
8003 || (fd = emacs_open (SSDATA (ENCODE_FILE (file)),
8004 O_RDONLY, 0)) < 0)
7932 { 8005 {
7933 image_error ("Cannot find image file `%s'", specified_file); 8006 image_error ("Cannot find image file `%s'", specified_file);
7934 return 0; 8007 return 0;
@@ -8655,8 +8728,10 @@ jpeg_load_body (struct frame *f, struct image *img,
8655 if (NILP (specified_data)) 8728 if (NILP (specified_data))
8656 { 8729 {
8657 int fd; 8730 int fd;
8658 Lisp_Object file = image_find_image_fd (specified_file, &fd); 8731 Lisp_Object file = image_find_image_file (specified_file);
8659 if (!STRINGP (file)) 8732 if (!STRINGP (file)
8733 || (fd = emacs_open (SSDATA (ENCODE_FILE (file)),
8734 O_RDONLY, 0)) < 0)
8660 { 8735 {
8661 image_error ("Cannot find image file `%s'", specified_file); 8736 image_error ("Cannot find image file `%s'", specified_file);
8662 return 0; 8737 return 0;
@@ -10153,7 +10228,7 @@ webp_load (struct frame *f, struct image *img)
10153 10228
10154 if (NILP (specified_data)) 10229 if (NILP (specified_data))
10155 { 10230 {
10156 int fd; 10231 image_fd fd;
10157 file = image_find_image_fd (specified_file, &fd); 10232 file = image_find_image_fd (specified_file, &fd);
10158 if (!STRINGP (file)) 10233 if (!STRINGP (file))
10159 { 10234 {
@@ -11552,7 +11627,7 @@ svg_load (struct frame *f, struct image *img)
11552 base_uri = image_spec_value (img->spec, QCbase_uri, NULL); 11627 base_uri = image_spec_value (img->spec, QCbase_uri, NULL);
11553 if (STRINGP (file_name)) 11628 if (STRINGP (file_name))
11554 { 11629 {
11555 int fd; 11630 image_fd fd;
11556 Lisp_Object file = image_find_image_fd (file_name, &fd); 11631 Lisp_Object file = image_find_image_fd (file_name, &fd);
11557 if (!STRINGP (file)) 11632 if (!STRINGP (file))
11558 { 11633 {