fast_thumbhash 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ca1251a50f86a6d61d03d4aca11a98b30336a72c12f5d5e8a15992c8d694638
4
- data.tar.gz: e77931c369a56aec1f619b4da9ef822623d5e0f4e839aab43e88ebc80ad5b748
3
+ metadata.gz: '029bcedcfcff9aeabbd3d052759f165228798ba5a4599747866b80c0e7cb2267'
4
+ data.tar.gz: c0284c796f2541a68ba0ce5d5f6d39362abc487d443ea92fe34f1cae84e49da2
5
5
  SHA512:
6
- metadata.gz: 66332f36f6e8d43256725abeb3c6a0e1f59a0cf8601516a3d5d8f6c0820259e7a7c2fa00afa5ece7b7eb834d78fd156407726d135d61e31d16b06a1e33547d52
7
- data.tar.gz: cb3673f55f78c9a64b00d5ebe442ff44fa966df878f2bcc1f511a0d7a4ca672412510d55c891afeddf53e65c864f678ea87ffcdbd679f1bcc385d63acc8e78e0
6
+ metadata.gz: 8305727fad3e3d55f31265f05f3bad5931f6a6cb90787e896a8aacde19d3fa5aa75c122a3d6a7a977b0f0703c95323556527401816641148f69c25001b5b30e9
7
+ data.tar.gz: 77e126d32164ec0531b0ee450a950e59e7f872ca18d2fbb46e5544171f35f44066835817fb0f6cccce2625e806e5af9a280c238e7bd104de2125065e6b6e3cb8
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.8
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fast_thumbhash (0.7.0)
4
+ fast_thumbhash (0.7.1)
5
5
  ffi
6
6
 
7
7
  GEM
@@ -52,6 +52,7 @@ GEM
52
52
 
53
53
  PLATFORMS
54
54
  arm64-darwin-21
55
+ arm64-darwin-22
55
56
  x86_64-darwin-18
56
57
  x86_64-darwin-20
57
58
  x86_64-darwin-21
@@ -67,14 +67,20 @@ encoded_channel encode_channel(double *channel, uint8_t nx, uint8_t ny, uint8_t
67
67
  return (encoded_channel){dc, ac, ac_length, scale};
68
68
  }
69
69
 
70
- void write_varying_factors(double *ac, int ac_size, uint8_t *thumbhash, uint8_t *ac_index) {
71
- for (int i = 0; i < ac_size; i++) {
72
- uint8_t index = (*ac_index) >> 1;
73
- thumbhash[index] |= (uint8_t) roundf(15.0 * ac[i]) << (((*ac_index)++ & 1) << 2);
70
+ uint8_t write_varying_factors(double *ac, int ac_size, uint8_t *thumbhash, uint8_t *ac_index)
71
+ {
72
+ uint8_t index;
73
+
74
+ for (int i = 0; i < ac_size; i++)
75
+ {
76
+ index = (*ac_index) >> 1;
77
+ thumbhash[index] |= (uint8_t)roundf(15.0 * ac[i]) << (((*ac_index)++ & 1) << 2);
74
78
  }
79
+
80
+ return index;
75
81
  }
76
82
 
77
- void rgba_to_thumbhash(uint8_t w, uint8_t h, uint8_t *rgba, uint8_t *thumbhash)
83
+ uint8_t rgba_to_thumbhash(uint8_t w, uint8_t h, uint8_t *rgba, uint8_t *thumbhash)
78
84
  {
79
85
  assert(w <= 100);
80
86
  assert(h <= 100);
@@ -143,28 +149,44 @@ void rgba_to_thumbhash(uint8_t w, uint8_t h, uint8_t *rgba, uint8_t *thumbhash)
143
149
  thumbhash[3] = (uint8_t)(header16 & 0xff);
144
150
  thumbhash[4] = (uint8_t)(header16 >> 8);
145
151
 
146
- if (has_alpha) {
147
- thumbhash[5] = (uint8_t) roundf(15.0 * ea.dc) | ((uint8_t) roundf(15.0 * ea.scale) << 4);
152
+ if (has_alpha)
153
+ {
154
+ thumbhash[5] = (uint8_t)roundf(15.0 * ea.dc) | ((uint8_t)roundf(15.0 * ea.scale) << 4);
148
155
  }
149
156
 
150
157
  uint8_t ac_start = has_alpha ? 6 : 5;
151
158
  uint8_t ac_index = 0;
152
159
 
153
- write_varying_factors(el.ac, el.ac_size, thumbhash + ac_start, &ac_index);
154
- write_varying_factors(ep.ac, ep.ac_size, thumbhash + ac_start, &ac_index);
155
- write_varying_factors(eq.ac, eq.ac_size, thumbhash + ac_start, &ac_index);
160
+ uint8_t max_written_indexes[] = {0, 0, 0, 0};
161
+
162
+ max_written_indexes[0] = write_varying_factors(el.ac, el.ac_size, thumbhash + ac_start, &ac_index);
163
+ max_written_indexes[1] = write_varying_factors(ep.ac, ep.ac_size, thumbhash + ac_start, &ac_index);
164
+ max_written_indexes[2] = write_varying_factors(eq.ac, eq.ac_size, thumbhash + ac_start, &ac_index);
156
165
 
157
- if (has_alpha) {
158
- write_varying_factors(ea.ac, ea.ac_size, thumbhash + ac_start, &ac_index);
166
+ if (has_alpha)
167
+ {
168
+ max_written_indexes[3] = write_varying_factors(ea.ac, ea.ac_size, thumbhash + ac_start, &ac_index);
159
169
  }
160
170
 
161
171
  free(el.ac);
162
172
  free(ep.ac);
163
173
  free(eq.ac);
164
174
 
165
- if (has_alpha) {
175
+ if (has_alpha)
176
+ {
166
177
  free(ea.ac);
167
178
  }
179
+
180
+ // store the largest number at max_written_indexes[0]
181
+ for (int i = 1; i < 4; ++i)
182
+ {
183
+ if (max_written_indexes[0] < max_written_indexes[i])
184
+ {
185
+ max_written_indexes[0] = max_written_indexes[i];
186
+ }
187
+ }
188
+
189
+ return max_written_indexes[0] + ac_start + 1;
168
190
  }
169
191
 
170
192
  double *decode_channel(uint8_t nx, uint8_t ny, double scale, uint8_t *hash, uint8_t ac_start, uint8_t *ac_index)
@@ -321,15 +343,14 @@ void hsv2rgb(float *hsv, uint8_t *rgb)
321
343
  * Decodes a ThumbHash to an RGBA image. RGB is not be premultiplied by A.
322
344
  */
323
345
  void thumbhash_to_rgba(
324
- uint8_t *hash,
325
- uint8_t w,
326
- uint8_t h,
327
- enum FillMode fill_mode,
328
- uint8_t *fill_color,
329
- double *homogeneous_transform,
330
- int saturation,
331
- uint8_t *rgba
332
- )
346
+ uint8_t *hash,
347
+ uint8_t w,
348
+ uint8_t h,
349
+ enum FillMode fill_mode,
350
+ uint8_t *fill_color,
351
+ double *homogeneous_transform,
352
+ int saturation,
353
+ uint8_t *rgba)
333
354
  {
334
355
  // Read the constants
335
356
  u_int32_t header24 = hash[0] | (hash[1] << 8) | (hash[2] << 16);
@@ -343,7 +364,8 @@ void thumbhash_to_rgba(
343
364
  double q_scale = (double)((header16 >> 9) & 63) / 63;
344
365
  bool is_landscape = (header16 >> 15) != 0;
345
366
  uint8_t lx = fmax(3, is_landscape ? has_alpha ? 5 : 7 : header16 & 7);
346
- uint8_t ly = fmax(3, is_landscape ? header16 & 7 : has_alpha ? 5 : 7);
367
+ uint8_t ly = fmax(3, is_landscape ? header16 & 7 : has_alpha ? 5
368
+ : 7);
347
369
  double a_dc = (double)has_alpha ? (hash[5] & 15) / 15 : 1;
348
370
  double a_scale = (double)(hash[5] >> 4) / 15;
349
371
 
@@ -380,7 +402,8 @@ void thumbhash_to_rgba(
380
402
 
381
403
  double r, g, b, a;
382
404
 
383
- if (fill_mode == CLAMP || fill_mode == BLUR) {
405
+ if (fill_mode == CLAMP || fill_mode == BLUR)
406
+ {
384
407
  if (x < 0)
385
408
  {
386
409
  x = 0;
@@ -401,7 +424,8 @@ void thumbhash_to_rgba(
401
424
 
402
425
  bool inside_image = x >= 0 && x <= 1.0 && y >= 0 && y <= 1.0;
403
426
 
404
- if (inside_image) {
427
+ if (inside_image)
428
+ {
405
429
  double l = l_dc, p = p_dc, q = q_dc;
406
430
  a = a_dc;
407
431
 
@@ -455,7 +479,9 @@ void thumbhash_to_rgba(
455
479
  b = l - 2.0 / 3.0 * p;
456
480
  r = (3.0 * l - b + q) / 2.0;
457
481
  g = r - q;
458
- } else {
482
+ }
483
+ else
484
+ {
459
485
  r = 255;
460
486
  g = 255;
461
487
  b = 255;
@@ -463,35 +489,37 @@ void thumbhash_to_rgba(
463
489
  }
464
490
 
465
491
  uint_fast8_t top[4] = {
466
- fmax(0, 255 * fmin(1, r)),
467
- fmax(0, 255 * fmin(1, g)),
468
- fmax(0, 255 * fmin(1, b)),
469
- fmax(0, 255 * fmin(1, a))
470
- };
471
-
472
- if (fill_color && fill_color[3] > 0) {
473
- double top_a = (double) top[3] / 255.0;
474
- double fill_color_a = (double) fill_color[3] / 255.0;
492
+ fmax(0, 255 * fmin(1, r)),
493
+ fmax(0, 255 * fmin(1, g)),
494
+ fmax(0, 255 * fmin(1, b)),
495
+ fmax(0, 255 * fmin(1, a))};
496
+
497
+ if (fill_color && fill_color[3] > 0)
498
+ {
499
+ double top_a = (double)top[3] / 255.0;
500
+ double fill_color_a = (double)fill_color[3] / 255.0;
475
501
  double inverse_top_a = 1.0 - top_a;
476
502
  double sum_a = top_a + fill_color_a * inverse_top_a;
477
503
 
478
504
  // Alpha compositing (top over fill_color)
479
- rgba[i] = roundf(((double) top[0] * top_a + (double) fill_color[0] * fill_color_a * inverse_top_a) / sum_a);
480
- rgba[i+1] = roundf(((double) top[1] * top_a + (double) fill_color[1] * fill_color_a * inverse_top_a) / sum_a);
481
- rgba[i+2] = roundf(((double) top[2] * top_a + (double) fill_color[2] * fill_color_a * inverse_top_a) / sum_a);
482
- rgba[i+3] = roundf(sum_a * 255.0);
483
- } else {
484
- rgba[i] = top[0];
485
- rgba[i+1] = top[1];
486
- rgba[i+2] = top[2];
487
- rgba[i+3] = top[3];
505
+ rgba[i] = roundf(((double)top[0] * top_a + (double)fill_color[0] * fill_color_a * inverse_top_a) / sum_a);
506
+ rgba[i + 1] = roundf(((double)top[1] * top_a + (double)fill_color[1] * fill_color_a * inverse_top_a) / sum_a);
507
+ rgba[i + 2] = roundf(((double)top[2] * top_a + (double)fill_color[2] * fill_color_a * inverse_top_a) / sum_a);
508
+ rgba[i + 3] = roundf(sum_a * 255.0);
509
+ }
510
+ else
511
+ {
512
+ rgba[i] = top[0];
513
+ rgba[i + 1] = top[1];
514
+ rgba[i + 2] = top[2];
515
+ rgba[i + 3] = top[3];
488
516
  }
489
517
 
490
518
  if (saturation)
491
519
  {
492
520
  float hsv[3] = {0};
493
521
  rgb2hsv(rgba + i, hsv);
494
- float mult = ((float) saturation + 100.0f) / 200.0f * 1.4f;
522
+ float mult = ((float)saturation + 100.0f) / 200.0f * 1.4f;
495
523
  hsv[1] = fminf(fmaxf(hsv[1] * mult, 0), 1.0f);
496
524
  hsv2rgb(hsv, rgba + i);
497
525
  }
@@ -3,34 +3,32 @@
3
3
 
4
4
  #include <stdint.h>
5
5
 
6
- enum FillMode {
6
+ enum FillMode
7
+ {
7
8
  SOLID = 0,
8
9
  BLUR = 1,
9
10
  CLAMP = 2,
10
11
  };
11
12
 
12
- void rgba_to_thumbhash(
13
- uint8_t w,
14
- uint8_t h,
15
- uint8_t *rgba,
16
- uint8_t *thumbhash
17
- );
13
+ uint8_t rgba_to_thumbhash(
14
+ uint8_t w,
15
+ uint8_t h,
16
+ uint8_t *rgba,
17
+ uint8_t *thumbhash);
18
18
 
19
19
  void thumb_size(
20
- uint8_t *hash,
21
- uint8_t max_size,
22
- uint8_t *size
23
- );
20
+ uint8_t *hash,
21
+ uint8_t max_size,
22
+ uint8_t *size);
24
23
 
25
24
  void thumbhash_to_rgba(
26
- uint8_t *hash,
27
- uint8_t w,
28
- uint8_t h,
29
- enum FillMode fill_mode,
30
- uint8_t *fill_color,
31
- double *homogeneous_transform,
32
- int saturation,
33
- uint8_t *rgba
34
- );
25
+ uint8_t *hash,
26
+ uint8_t w,
27
+ uint8_t h,
28
+ enum FillMode fill_mode,
29
+ uint8_t *fill_color,
30
+ double *homogeneous_transform,
31
+ int saturation,
32
+ uint8_t *rgba);
35
33
 
36
34
  #endif
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FastThumbhash
4
- VERSION = "0.7.0"
4
+ VERSION = "0.7.1"
5
5
  end
@@ -155,10 +155,9 @@ module FastThumbhash
155
155
 
156
156
  thumbhash_pointer = FFI::MemoryPointer.new(:uint8, 25)
157
157
 
158
- Library.rgba_to_thumbhash(width, height, rgba_pointer, thumbhash_pointer)
158
+ length = Library.rgba_to_thumbhash(width, height, rgba_pointer, thumbhash_pointer)
159
159
 
160
- result = thumbhash_pointer.read_array_of_uint8(25)
161
- result.pop while result.last.zero?
160
+ result = thumbhash_pointer.read_array_of_uint8(length)
162
161
 
163
162
  result.pack("C*")
164
163
  ensure
@@ -178,6 +177,6 @@ module FastThumbhash
178
177
 
179
178
  attach_function :thumb_size, %i[pointer uint8 pointer], :size_t
180
179
  attach_function :thumbhash_to_rgba, %i[pointer uint8 uint8 fill_mode pointer pointer int pointer], :void
181
- attach_function :rgba_to_thumbhash, %i[uint8 uint8 pointer pointer], :void
180
+ attach_function :rgba_to_thumbhash, %i[uint8 uint8 pointer pointer], :uint8
182
181
  end
183
182
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast_thumbhash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Verna
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-11 00:00:00.000000000 Z
11
+ date: 2023-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -35,6 +35,7 @@ extra_rdoc_files: []
35
35
  files:
36
36
  - ".rspec"
37
37
  - ".rubocop.yml"
38
+ - ".ruby-version"
38
39
  - CODE_OF_CONDUCT.md
39
40
  - Gemfile
40
41
  - Gemfile.lock