Skip to content

Commit

Permalink
chore(sdk)!: Remove image-proc feature and functions to generate a th…
Browse files Browse the repository at this point in the history
…umbnail

Signed-off-by: Kévin Commaille <[email protected]>
  • Loading branch information
zecakeh authored and jmartinesp committed Oct 16, 2024
1 parent ee4ef2e commit 9999d3b
Show file tree
Hide file tree
Showing 13 changed files with 3 additions and 533 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ jobs:
- markdown
- socks
- sso-login
- image-proc

steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
run: |
rustup run stable cargo tarpaulin \
--skip-clean --profile cov --out xml \
--features experimental-widgets,testing,image-proc
--features experimental-widgets,testing
env:
CARGO_PROFILE_COV_INHERITS: 'dev'
CARGO_PROFILE_COV_DEBUG: 1
Expand Down
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 0 additions & 4 deletions crates/matrix-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ Breaking changes:
`Media::get_file`/`Media::remove_file`/`Media::get_thumbnail`/`Media::remove_thumbnail`
- A custom sliding sync proxy set with `ClientBuilder::sliding_sync_proxy` now takes precedence over a discovered proxy.
- `Client::get_profile` was moved to `Account` and renamed to `Account::fetch_user_profile_of`. `Account::get_profile` was renamed to `Account::fetch_user_profile`.
- `generate_image_thumbnail` now returns a `Thumbnail`.
- It is now possible to select the format of a generated thumbnail.
- `generate_image_thumbnail` takes a `ThumbnailFormat`.
- `AttachmentConfig::generate_thumbnail` takes a `ThumbnailFormat`.
- The `HttpError::UnableToCloneRequest` error variant has been removed because it was never used or
generated by the SDK.
- The `Error::InconsistentState` error variant has been removed because it was never used or
Expand Down
10 changes: 1 addition & 9 deletions crates/matrix-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ native-tls = ["reqwest/native-tls"]
rustls-tls = ["reqwest/rustls-tls"]
socks = ["reqwest/socks"]
sso-login = ["dep:axum", "dep:rand", "dep:tower"]
image-proc = ["dep:image"]
image-rayon = ["image-proc", "image?/rayon"]

uniffi = ["dep:uniffi", "matrix-sdk-base/uniffi", "dep:matrix-sdk-ffi-macros"]

Expand All @@ -63,7 +61,7 @@ experimental-sliding-sync = [
]
experimental-widgets = ["dep:language-tags", "dep:uuid"]

docsrs = ["e2e-encryption", "sqlite", "indexeddb", "sso-login", "qrcode", "image-proc"]
docsrs = ["e2e-encryption", "sqlite", "indexeddb", "sso-login", "qrcode"]

[dependencies]
anyhow = { workspace = true, optional = true }
Expand Down Expand Up @@ -116,12 +114,6 @@ uuid = { version = "1.4.1", features = ["serde", "v4"], optional = true }
vodozemac = { workspace = true }
zeroize = { workspace = true }

[dependencies.image]
version = "0.25.1"
default-features = false
features = ["default-formats"]
optional = true

[target.'cfg(target_arch = "wasm32")'.dependencies]
gloo-timers = { version = "0.3.0", features = ["futures"] }
reqwest = { workspace = true }
Expand Down
2 changes: 0 additions & 2 deletions crates/matrix-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ The following crate feature flags are available:
| `anyhow` | No | Better logging for event handlers that return `anyhow::Result` |
| `e2e-encryption` | Yes | End-to-end encryption (E2EE) support |
| `eyre` | No | Better logging for event handlers that return `eyre::Result` |
| `image-proc` | No | Image processing for generating thumbnails |
| `image-rayon` | No | Enables faster image processing |
| `js` | No | Enables JavaScript API usage on WASM (does nothing on other targets) |
| `markdown` | No | Support for sending Markdown-formatted messages |
| `qrcode` | Yes | QR code verification support |
Expand Down
174 changes: 0 additions & 174 deletions crates/matrix-sdk/src/attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,8 @@

//! Types and traits for attachments.
#[cfg(feature = "image-proc")]
use std::io::{BufRead, Cursor, Seek};
use std::time::Duration;

#[cfg(feature = "image-proc")]
use image::GenericImageView;
#[cfg(feature = "image-proc")]
pub use image::ImageFormat;
use ruma::{
assign,
events::{
Expand All @@ -34,9 +28,6 @@ use ruma::{
OwnedTransactionId, TransactionId, UInt,
};

#[cfg(feature = "image-proc")]
use crate::ImageError;

/// Base metadata about an image.
#[derive(Debug, Clone)]
pub struct BaseImageInfo {
Expand Down Expand Up @@ -198,12 +189,6 @@ pub struct AttachmentConfig {
pub(crate) caption: Option<String>,
pub(crate) formatted_caption: Option<FormattedBody>,
pub(crate) mentions: Option<Mentions>,
#[cfg(feature = "image-proc")]
pub(crate) generate_thumbnail: bool,
#[cfg(feature = "image-proc")]
pub(crate) thumbnail_size: Option<(u32, u32)>,
#[cfg(feature = "image-proc")]
pub(crate) thumbnail_format: ThumbnailFormat,
}

impl AttachmentConfig {
Expand All @@ -214,42 +199,12 @@ impl AttachmentConfig {
Self::default()
}

/// Generate the thumbnail to send for this media.
///
/// Uses [`generate_image_thumbnail()`].
///
/// Thumbnails can only be generated for supported image attachments. For
/// more information, see the [image](https://github.com/image-rs/image)
/// crate.
///
/// If generating the thumbnail failed, the error will be logged and sending
/// the attachment will proceed without a thumbnail.
///
/// # Arguments
///
/// * `size` - The size of the thumbnail in pixels as a `(width, height)`
/// tuple. If set to `None`, defaults to `(800, 600)`.
///
/// * `format` - The image format to use to encode the thumbnail.
#[cfg(feature = "image-proc")]
#[must_use]
pub fn generate_thumbnail(mut self, size: Option<(u32, u32)>, format: ThumbnailFormat) -> Self {
self.generate_thumbnail = true;
self.thumbnail_size = size;
self.thumbnail_format = format;
self
}

/// Create a new default `AttachmentConfig` with a `thumbnail`.
///
/// # Arguments
///
/// * `thumbnail` - The thumbnail of the media. If the `content_type` does
/// not support it (eg audio clips), it is ignored.
///
/// To generate automatically a thumbnail from an image, use
/// [`AttachmentConfig::new()`] and
/// [`AttachmentConfig::generate_thumbnail()`].
pub fn with_thumbnail(thumbnail: Thumbnail) -> Self {
Self { thumbnail: Some(thumbnail), ..Default::default() }
}
Expand Down Expand Up @@ -309,132 +264,3 @@ impl AttachmentConfig {
self
}
}

/// Generate a thumbnail for an image.
///
/// This is a convenience method that uses the
/// [image](https://github.com/image-rs/image) crate.
///
/// # Arguments
/// * `content_type` - The type of the media, this will be used as the
/// content-type header.
///
/// * `reader` - A `Reader` that will be used to fetch the raw bytes of the
/// media.
///
/// * `size` - The size of the thumbnail in pixels as a `(width, height)` tuple.
/// If set to `None`, defaults to `(800, 600)`.
///
/// * `format` - The image format to use to encode the thumbnail.
///
/// # Examples
///
/// ```no_run
/// use std::{io::Cursor, path::PathBuf};
///
/// use matrix_sdk::attachment::{
/// generate_image_thumbnail, AttachmentConfig, Thumbnail, ThumbnailFormat,
/// };
/// use mime;
/// # use matrix_sdk::{Client, ruma::room_id };
/// # use url::Url;
/// #
/// # async {
/// # let homeserver = Url::parse("http://localhost:8080")?;
/// # let mut client = Client::new(homeserver).await?;
/// # let room_id = room_id!("!test:localhost");
/// let path = PathBuf::from("/home/example/my-cat.jpg");
/// let image = tokio::fs::read(path).await?;
///
/// let cursor = Cursor::new(&image);
/// let thumbnail = generate_image_thumbnail(
/// &mime::IMAGE_JPEG,
/// cursor,
/// None,
/// ThumbnailFormat::Original,
/// )?;
/// let config = AttachmentConfig::with_thumbnail(thumbnail);
///
/// if let Some(room) = client.get_room(&room_id) {
/// room.send_attachment(
/// "my_favorite_cat.jpg",
/// &mime::IMAGE_JPEG,
/// image,
/// config,
/// )
/// .await?;
/// }
/// # anyhow::Ok(()) };
/// ```
#[cfg(feature = "image-proc")]
pub fn generate_image_thumbnail<R: BufRead + Seek>(
content_type: &mime::Mime,
reader: R,
size: Option<(u32, u32)>,
format: ThumbnailFormat,
) -> Result<Thumbnail, ImageError> {
use std::str::FromStr;

let Some(image_format) = ImageFormat::from_mime_type(content_type) else {
return Err(ImageError::FormatNotSupported);
};

let image = image::load(reader, image_format)?;
let (original_width, original_height) = image.dimensions();

let (width, height) = size.unwrap_or((800, 600));

// Don't generate a thumbnail if it would be bigger than or equal to the
// original.
if height >= original_height && width >= original_width {
return Err(ImageError::ThumbnailBiggerThanOriginal);
}

let thumbnail = image.thumbnail(width, height);
let (thumbnail_width, thumbnail_height) = thumbnail.dimensions();

let thumbnail_format = match format {
ThumbnailFormat::Always(format) => format,
ThumbnailFormat::Fallback(format) if !image_format.writing_enabled() => format,
ThumbnailFormat::Fallback(_) | ThumbnailFormat::Original => image_format,
};

let mut data: Vec<u8> = vec![];
thumbnail.write_to(&mut Cursor::new(&mut data), thumbnail_format)?;
let data_size = data.len() as u32;

let content_type = mime::Mime::from_str(thumbnail_format.to_mime_type())?;

let info = BaseThumbnailInfo {
width: Some(thumbnail_width.into()),
height: Some(thumbnail_height.into()),
size: Some(data_size.into()),
};

Ok(Thumbnail { data, content_type, info: Some(info) })
}

/// The format to use for encoding the thumbnail.
#[cfg(feature = "image-proc")]
#[derive(Debug, Default, Clone, Copy)]
pub enum ThumbnailFormat {
/// Always use this format.
///
/// Will always return an error if this format is not writable by the
/// `image` crate.
Always(ImageFormat),
/// Try to use the same format as the original image, and fallback to this
/// one if the original format is not writable.
///
/// Will return an error if both the original format and this format are not
/// writable by the `image` crate.
Fallback(ImageFormat),
/// Only try to use the format of the original image.
///
/// Will return an error if the original format is not writable by the
/// `image` crate.
///
/// This is the default.
#[default]
Original,
}
26 changes: 0 additions & 26 deletions crates/matrix-sdk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,6 @@ pub enum Error {
#[error(transparent)]
UserTagName(#[from] InvalidUserTagName),

/// An error while processing images.
#[cfg(feature = "image-proc")]
#[error(transparent)]
ImageError(#[from] ImageError),

/// An error occurred within sliding-sync
#[cfg(feature = "experimental-sliding-sync")]
#[error(transparent)]
Expand Down Expand Up @@ -500,27 +495,6 @@ impl From<ReqwestError> for Error {
}
}

/// All possible errors that can happen during image processing.
#[cfg(feature = "image-proc")]
#[derive(Error, Debug)]
pub enum ImageError {
/// Error processing the image data.
#[error(transparent)]
Proc(#[from] image::ImageError),

/// Error parsing the mimetype of the image.
#[error(transparent)]
Mime(#[from] mime::FromStrError),

/// The image format is not supported.
#[error("the image format is not supported")]
FormatNotSupported,

/// The thumbnail size is bigger than the original image.
#[error("the thumbnail size is bigger than the original image size")]
ThumbnailBiggerThanOriginal,
}

/// Errors that can happen when interacting with the beacon API.
#[derive(Debug, Error)]
pub enum BeaconError {
Expand Down
2 changes: 0 additions & 2 deletions crates/matrix-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ pub use authentication::{AuthApi, AuthSession, SessionTokens};
pub use client::{
sanitize_server_name, Client, ClientBuildError, ClientBuilder, LoopCtrl, SessionChange,
};
#[cfg(feature = "image-proc")]
pub use error::ImageError;
pub use error::{
Error, HttpError, HttpResult, NotificationSettingsError, RefreshTokenError, Result,
RumaApiError,
Expand Down
Loading

0 comments on commit 9999d3b

Please sign in to comment.