From 5e88baecd1c37e793ceca6c8215e84f068e6b7ec Mon Sep 17 00:00:00 2001 From: manti <133025162+manti-X@users.noreply.github.com> Date: Wed, 12 Nov 2025 06:37:54 +0100 Subject: [PATCH] Add CiaoPlus (#11480) * add ciaoplus * use api and refactor * getMangaUrl --- src/ja/ciaoplus/build.gradle | 8 + .../ciaoplus/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 6513 bytes .../ciaoplus/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 3400 bytes .../ciaoplus/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 9922 bytes .../res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 19141 bytes .../res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 30856 bytes .../extension/ja/ciaoplus/CiaoPlus.kt | 338 ++++++++++++++++++ .../tachiyomi/extension/ja/ciaoplus/Dto.kt | 130 +++++++ .../extension/ja/ciaoplus/ImageInterceptor.kt | 127 +++++++ 9 files changed, 603 insertions(+) create mode 100644 src/ja/ciaoplus/build.gradle create mode 100644 src/ja/ciaoplus/res/mipmap-hdpi/ic_launcher.png create mode 100644 src/ja/ciaoplus/res/mipmap-mdpi/ic_launcher.png create mode 100644 src/ja/ciaoplus/res/mipmap-xhdpi/ic_launcher.png create mode 100644 src/ja/ciaoplus/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 src/ja/ciaoplus/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/CiaoPlus.kt create mode 100644 src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/Dto.kt create mode 100644 src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/ImageInterceptor.kt diff --git a/src/ja/ciaoplus/build.gradle b/src/ja/ciaoplus/build.gradle new file mode 100644 index 000000000..a4fdf8920 --- /dev/null +++ b/src/ja/ciaoplus/build.gradle @@ -0,0 +1,8 @@ +ext { + extName = 'Ciao Plus' + extClass = '.CiaoPlus' + extVersionCode = 1 + isNsfw = false +} + +apply from: "$rootDir/common.gradle" diff --git a/src/ja/ciaoplus/res/mipmap-hdpi/ic_launcher.png b/src/ja/ciaoplus/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..9bb75ab05c748ec57f9cbedc219e8b2d341b0b27 GIT binary patch literal 6513 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 XCrAZFj?ZDs00000NkvXXu0mjfIn;~7 literal 0 HcmV?d00001 diff --git a/src/ja/ciaoplus/res/mipmap-mdpi/ic_launcher.png b/src/ja/ciaoplus/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..bcde9a713b87436d3e16a3e950242de7d9cfab18 GIT binary patch literal 3400 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 AuK)l5 literal 0 HcmV?d00001 diff --git a/src/ja/ciaoplus/res/mipmap-xxhdpi/ic_launcher.png b/src/ja/ciaoplus/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..caa1de01acc1fafc3e35e0f8bac3490f006146eb GIT binary patch literal 19141 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

cKAs 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 literal 0 HcmV?d00001 diff --git a/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/CiaoPlus.kt b/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/CiaoPlus.kt new file mode 100644 index 000000000..10a7796d5 --- /dev/null +++ b/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/CiaoPlus.kt @@ -0,0 +1,338 @@ +package eu.kanade.tachiyomi.extension.ja.ciaoplus + +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST +import eu.kanade.tachiyomi.source.model.Filter +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.online.HttpSource +import keiyoushi.utils.firstInstance +import keiyoushi.utils.parseAs +import okhttp3.FormBody +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.Request +import okhttp3.Response +import okio.ByteString.Companion.encodeUtf8 +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Date +import java.util.GregorianCalendar +import java.util.Locale +import java.util.TimeZone + +class CiaoPlus : HttpSource() { + override val name = "Ciao Plus" + override val baseUrl = "https://ciao.shogakukan.co.jp" + override val lang = "ja" + override val supportsLatest = true + + private val apiUrl = "https://api.ciao.shogakukan.co.jp" + private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.JAPAN) + private val latestRequestDateFormat = SimpleDateFormat("yyyyMMdd", Locale.JAPAN) + private val latestResponseDateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.JAPAN) + private val pageLimit = 25 + + override fun headersBuilder() = super.headersBuilder() + .add("Referer", "$baseUrl/") + + override val client = network.cloudflareClient.newBuilder() + .addInterceptor(ImageInterceptor()) + .build() + + // Popular + override fun popularMangaRequest(page: Int): Request { + val offset = (page - 1) * pageLimit + val url = apiUrl.toHttpUrl().newBuilder() + .addPathSegments("ranking/all") + .addQueryParameter("platform", "3") + .addQueryParameter("ranking_id", "1") + .addQueryParameter("offset", offset.toString()) + .addQueryParameter("limit", "51") + .addQueryParameter("is_top", "0") + .build() + return hashedGet(url) + } + + override fun popularMangaParse(response: Response): MangasPage { + val requestUrl = response.request.url.toString() + val rankingResult = response.parseAs() + val titleIds = rankingResult.rankingTitleList.map { it.id.toString().padStart(5, '0') } + if (titleIds.isEmpty()) { + return MangasPage(emptyList(), false) + } + + val hasNextPage = titleIds.size > pageLimit + val mangaIdsToFetch = if (hasNextPage) titleIds.dropLast(1) else titleIds + val detailsUrl = apiUrl.toHttpUrl().newBuilder() + .addPathSegments("title/list") + .addQueryParameter("platform", "3") + .addQueryParameter("title_id_list", mangaIdsToFetch.joinToString(",")) + .build() + + val detailsRequest = hashedGet(detailsUrl) + val detailsResponse = client.newCall(detailsRequest).execute() + if (!detailsResponse.isSuccessful) { + throw Exception("Failed to fetch title details: ${detailsResponse.code} - ${detailsResponse.body.string()}") + } + + val detailsResult = detailsResponse.parseAs() + val mangas = detailsResult.titleList.map { it.toSManga() } + + if (requestUrl.contains("/genre/")) { + return MangasPage(mangas.reversed(), hasNextPage) + } + return MangasPage(mangas, hasNextPage) + } + + // Latest + override fun latestUpdatesRequest(page: Int): Request { + val calendar = GregorianCalendar(TimeZone.getTimeZone("Asia/Tokyo")).apply { + time = Date() + add(Calendar.DAY_OF_MONTH, -(page - 1)) + } + val dateString = latestRequestDateFormat.format(calendar.time) + + val url = apiUrl.toHttpUrl().newBuilder() + .addPathSegments("web/title/ids") + .addQueryParameter("updated_at", dateString) + .addQueryParameter("platform", "3") + .build() + return hashedGet(url) + } + + override fun latestUpdatesParse(response: Response): MangasPage { + val result = response.parseAs() + val today = GregorianCalendar(TimeZone.getTimeZone("Asia/Tokyo")).time + val mangas = result.updateEpisodeTitles + .filterKeys { + if (it.startsWith("2099")) return@filterKeys false + val entryDate = latestResponseDateFormat.parse(it) + !entryDate!!.after(today) + } + .flatMap { it.value } + .distinctBy { it.titleId } + .map { it.toSManga() } + return MangasPage(mangas, false) + } + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + if (query.isNotBlank()) { + val url = apiUrl.toHttpUrl().newBuilder() + .addPathSegments("search/title") + .addQueryParameter("keyword", query) + .addQueryParameter("limit", "99999") + .addQueryParameter("platform", "3") + .build() + return hashedGet(url) + } + + val genreFilter = filters.firstInstance() + val uriPart = genreFilter.toUriPart() + val url = if (uriPart.startsWith("/genre/")) { + val genreId = uriPart.substringAfter("/genre/") + apiUrl.toHttpUrl().newBuilder() + .addPathSegments("search/title") + .addQueryParameter("platform", "3") + .addQueryParameter("genre_id", genreId) + .addQueryParameter("limit", "99999") + .build() + } else { + val rankingId = uriPart.substringAfter("/ranking/") + val offset = (page - 1) * pageLimit + apiUrl.toHttpUrl().newBuilder() + .addPathSegments("ranking/all") + .addQueryParameter("platform", "3") + .addQueryParameter("ranking_id", rankingId) + .addQueryParameter("offset", offset.toString()) + .addQueryParameter("limit", "51") + .addQueryParameter("is_top", "0") + .build() + } + return hashedGet(url) + } + + override fun searchMangaParse(response: Response): MangasPage { + val requestUrl = response.request.url.toString() + if (requestUrl.contains("/search/title")) { + val result = response.parseAs() + val mangas = result.titleList.map { it.toSManga() } + return MangasPage(mangas, false) + } + return popularMangaParse(response) + } + + // Details + override fun getMangaUrl(manga: SManga): String { + return baseUrl + manga.url + } + + override fun mangaDetailsRequest(manga: SManga): Request { + val titleId = manga.url.substringAfter("/title/") + val url = apiUrl.toHttpUrl().newBuilder() + .addPathSegments("title/list") + .addQueryParameter("platform", "3") + .addQueryParameter("title_id_list", titleId) + .build() + return hashedGet(url) + } + + override fun mangaDetailsParse(response: Response): SManga { + val details = response.parseAs() + val result = details.webTitle.first() + return SManga.create().apply { + title = result.titleName + author = result.authorText + description = result.introductionText + if (result.genreIdList.isNotEmpty()) { + val genreApiUrl = apiUrl.toHttpUrl().newBuilder() + .addPathSegments("genre/list") + .addQueryParameter("platform", "3") + .addQueryParameter("genre_id_list", result.genreIdList.joinToString(",")) + .build() + + val genreRequest = hashedGet(genreApiUrl) + val genreResponse = client.newCall(genreRequest).execute() + + if (genreResponse.isSuccessful) { + val genreResult = genreResponse.parseAs() + genre = genreResult.genreList.joinToString { it.genreName } + } + } + } + } + + // Chapters + override fun chapterListRequest(manga: SManga): Request { + return mangaDetailsRequest(manga) + } + + override fun chapterListParse(response: Response): List { + val details = response.parseAs() + val resultIds = details.webTitle.first() + val episodeIds = resultIds.episodeIdList.map { it.toString() } + if (episodeIds.isEmpty()) { + return emptyList() + } + + val formBody = FormBody.Builder() + .add("platform", "3") + .add("episode_id_list", episodeIds.joinToString(",")) + .build() + + val params = (0 until formBody.size).associate { formBody.name(it) to formBody.value(it) } + val hash = generateHash(params) + + val postHeaders = headersBuilder() + .add("Origin", baseUrl) + .add("x-bambi-is-crawler", "false") + .add("x-bambi-hash", hash) + .build() + + val apiRequest = POST("$apiUrl/episode/list", postHeaders, formBody) + val apiResponse = client.newCall(apiRequest).execute() + + if (!apiResponse.isSuccessful) { + throw Exception("API request failed with code ${apiResponse.code}: ${apiResponse.body.string()}") + } + + val result = apiResponse.parseAs() + + return result.episodeList.map { it.toSChapter(resultIds.titleName, dateFormat) }.reversed() + } + + // Pages + /* + override fun fetchPageList(chapter: SChapter): Observable> { + return client.newCall(pageListRequest(chapter)) + .asObservable() + .map { response -> + if (!response.isSuccessful) { + if (response.code == 400) { + throw Exception("This chapter is locked. Log in via WebView and rent or purchase this chapter to read.") + } + throw Exception("HTTP error ${response.code}") + } + pageListParse(response) + } + } + */ + + override fun pageListParse(response: Response): List { + val apiResponse = response.parseAs() + val seed = apiResponse.scrambleSeed + val ver = apiResponse.scrambleVer + val fragment = if (ver == 2) "scramble_seed_v2" else "scramble_seed" + return apiResponse.pageList.mapIndexed { index, imageUrl -> + Page(index, imageUrl = "$imageUrl#$fragment=$seed") + } + } + + override fun pageListRequest(chapter: SChapter): Request { + val episodeId = chapter.url.substringAfter("episode/") + val url = "$apiUrl/web/episode/viewer".toHttpUrl().newBuilder() + .addQueryParameter("platform", "3") + .addQueryParameter("episode_id", episodeId) + .build() + return hashedGet(url) + } + + private fun generateHash(params: Map): String { + val paramStrings = params.toSortedMap().map { (key, value) -> + getHashedParam(key, value) + } + val joinedParams = paramStrings.joinToString(",") + val hash1 = joinedParams.encodeUtf8().sha256().hex() + return hash1.encodeUtf8().sha512().hex() + } + + private fun getHashedParam(key: String, value: String): String { + val keyHash = key.encodeUtf8().sha256().hex() + val valueHash = value.encodeUtf8().sha512().hex() + return "${keyHash}_$valueHash" + } + + private fun hashedGet(url: HttpUrl): Request { + val queryParams = url.queryParameterNames.associateWith { url.queryParameter(it)!! } + val hash = generateHash(queryParams) + val newHeaders = headersBuilder() + .add("x-bambi-hash", hash) + .build() + return GET(url, newHeaders) + } + + override fun getFilterList() = FilterList( + Filter.Header("NOTE: Search query will ignore genre filter"), + GenreFilter(getGenreList()), + ) + + private class GenreFilter(private val genres: Array>) : + Filter.Select("Filter by", genres.map { it.first }.toTypedArray()) { + fun toUriPart() = genres[state].second + } + + private fun getGenreList() = arrayOf( + Pair("(ランキング) まんが総合", "/ranking/1"), + Pair("(ランキング) 急上昇", "/ranking/2"), + Pair("(ランキング) 読切", "/ranking/3"), + Pair("(ランキング) ラブ", "/ranking/4"), + Pair("(ランキング) ホラー・ミステリー", "/ranking/5"), + Pair("(ランキング) ファンタジー", "/ranking/6"), + Pair("(ランキング) ギャグ・エッセイ", "/ranking/7"), + Pair("ギャグ・エッセイ", "/genre/1"), + Pair("ラブ", "/genre/2"), + Pair("ホラー・ミステリー", "/genre/3"), + Pair("家族", "/genre/4"), + Pair("青春・学園", "/genre/5"), + Pair("友情", "/genre/6"), + Pair("ファンタジー", "/genre/7"), + Pair("ドリーム・サクセス", "/genre/8"), + Pair("異世界", "/genre/9"), + ) + + // Unsupported + override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException() +} diff --git a/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/Dto.kt b/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/Dto.kt new file mode 100644 index 000000000..38766e768 --- /dev/null +++ b/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/Dto.kt @@ -0,0 +1,130 @@ +package eu.kanade.tachiyomi.extension.ja.ciaoplus + +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import keiyoushi.utils.tryParse +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import java.text.SimpleDateFormat + +@Serializable +class RankingApiResponse( + @SerialName("ranking_title_list") val rankingTitleList: List, +) + +@Serializable +class RankingTitleId( + val id: Int, +) + +@Serializable +class TitleListResponse( + @SerialName("title_list") val titleList: List, +) + +@Serializable +class TitleDetail( + @SerialName("title_id") private val titleId: Int, + @SerialName("title_name") private val titleName: String, + @SerialName("thumbnail_image_url") private val thumbnailImageUrl: String?, +) { + fun toSManga(): SManga = SManga.create().apply { + val paddedId = titleId.toString().padStart(5, '0') + url = "/comics/title/$paddedId" + title = titleName + thumbnail_url = thumbnailImageUrl + } +} + +@Serializable +class LatestTitleListResponse( + @SerialName("update_episode_titles") val updateEpisodeTitles: Map>, +) + +@Serializable +class LatestTitleDetail( + @SerialName("title_id") val titleId: Int, + @SerialName("title_name") private val titleName: String, + @SerialName("thumbnail_image") private val thumbnailImageUrl: String?, +) { + fun toSManga(): SManga = SManga.create().apply { + val paddedId = titleId.toString().padStart(5, '0') + url = "/comics/title/$paddedId" + title = titleName + thumbnail_url = thumbnailImageUrl + } +} + +@Serializable +class EpisodeListResponse( + @SerialName("episode_list") val episodeList: List, +) + +@Serializable +class Episode( + @SerialName("episode_id") private val episodeId: Int, + @SerialName("episode_name") private val episodeName: String, + private val index: Int, + @SerialName("start_time") private val startTime: String, + private val point: Int, + @SerialName("title_id") private val titleId: Int, + private val badge: Int, + @SerialName("rental_finish_time") private val rentalFinishTime: String? = null, +) { + fun toSChapter(mangaTitle: String, dateFormat: SimpleDateFormat): SChapter = SChapter.create().apply { + val paddedId = titleId.toString().padStart(5, '0') + url = "/comics/title/$paddedId/episode/$episodeId" + + val originalChapterName = episodeName.trim() + val chapterName = if (originalChapterName.startsWith(mangaTitle.trim())) { + // If entry title is in chapter name, that part of the chapter name is missing, so index is added here to the name + "【第${index}話】 $originalChapterName" + } else { + originalChapterName + } + + // It is possible to read paid chapters even though you have to purchase them on the website, so leaving this here in case they change it + /* + name = if (point > 0 && badge != 3 && rentalFinishTime == null) { + "🔒 $chapterName" + } else { + chapterName + } + */ + + name = chapterName + chapter_number = index.toFloat() + date_upload = dateFormat.tryParse(startTime) + } +} + +@Serializable +class DetailResponse( + @SerialName("title_list") val webTitle: List, +) + +@Serializable +class WebTitle( + @SerialName("title_name") val titleName: String, + @SerialName("author_text") val authorText: String, + @SerialName("introduction_text") val introductionText: String, + @SerialName("genre_id_list") val genreIdList: List, + @SerialName("episode_id_list") val episodeIdList: List, +) + +@Serializable +class ViewerApiResponse( + @SerialName("page_list") val pageList: List, + @SerialName("scramble_seed") val scrambleSeed: Long, + @SerialName("scramble_ver") val scrambleVer: Int, +) + +@Serializable +class GenreListResponse( + @SerialName("genre_list") val genreList: List, +) + +@Serializable +class GenreDetail( + @SerialName("genre_name") val genreName: String, +) diff --git a/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/ImageInterceptor.kt b/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/ImageInterceptor.kt new file mode 100644 index 000000000..ae253a67e --- /dev/null +++ b/src/ja/ciaoplus/src/eu/kanade/tachiyomi/extension/ja/ciaoplus/ImageInterceptor.kt @@ -0,0 +1,127 @@ +package eu.kanade.tachiyomi.extension.ja.ciaoplus + +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Canvas +import android.graphics.Rect +import okhttp3.Interceptor +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.Response +import okhttp3.ResponseBody +import okhttp3.ResponseBody.Companion.toResponseBody +import java.io.ByteArrayOutputStream + +class ImageInterceptor : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + val fragment = request.url.fragment + if (fragment.isNullOrEmpty()) { + return chain.proceed(request) + } + + val (seed, version) = when { + fragment.startsWith("scramble_seed_v2=") -> { + Pair(fragment.substringAfter("scramble_seed_v2=").toLong(), 2) + } + fragment.startsWith("scramble_seed=") -> { + Pair(fragment.substringAfter("scramble_seed=").toLong(), 1) + } + else -> return chain.proceed(request) + } + + val response = chain.proceed(request) + val descrambledBody = descrambleImage(response.body, seed, version) + + return response.newBuilder().body(descrambledBody).build() + } + + private class Coord(val x: Int, val y: Int) + + private class CoordPair(val source: Coord, val dest: Coord) + + private fun xorshift32(seed: UInt): UInt { + var n = seed + n = n xor (n shl 13) + n = n xor (n shr 17) + n = n xor (n shl 5) + return n + } + + private fun getUnscrambledCoords(seed: Long): List { + var seed32 = seed.toUInt() + val pairs = mutableListOf>() + + for (i in 0 until 16) { + seed32 = xorshift32(seed32) + pairs.add(seed32 to i) + } + + pairs.sortBy { it.first } + val sortedVal = pairs.map { it.second } + + return sortedVal.mapIndexed { i, e -> + CoordPair( + source = Coord(x = e % 4, y = e / 4), + dest = Coord(x = i % 4, y = i / 4), + ) + } + } + + private fun descrambleImage(responseBody: ResponseBody, seed: Long, version: Int): ResponseBody { + val unscrambledCoords = getUnscrambledCoords(seed) + val originalBitmap = BitmapFactory.decodeStream(responseBody.byteStream()) + ?: throw Exception("Failed to decode image stream") + + val originalWidth = originalBitmap.width + val originalHeight = originalBitmap.height + + val descrambledBitmap = Bitmap.createBitmap(originalWidth, originalHeight, originalBitmap.config) + val canvas = Canvas(descrambledBitmap) + + val (tileWidth, tileHeight) = when (version) { + 2 -> { + val getTile = { size: Int -> (size / 32) * 8 } + Pair(getTile(originalWidth), getTile(originalHeight)) + } + else -> { + val getTile = { size: Int -> (size / 8 * 8) / 4 } + Pair(getTile(originalWidth), getTile(originalHeight)) + } + } + + unscrambledCoords.forEach { coord -> + val sx = coord.source.x * tileWidth + val sy = coord.source.y * tileHeight + val dx = coord.dest.x * tileWidth + val dy = coord.dest.y * tileHeight + + val srcRect = Rect(sx, sy, sx + tileWidth, sy + tileHeight) + val destRect = Rect(dx, dy, dx + tileWidth, dy + tileHeight) + + canvas.drawBitmap(originalBitmap, srcRect, destRect, null) + } + + if (version == 2) { + val processedWidth = tileWidth * 4 + val processedHeight = tileHeight * 4 + if (originalWidth > processedWidth) { + val srcRect = Rect(processedWidth, 0, originalWidth, originalHeight) + val destRect = Rect(processedWidth, 0, originalWidth, originalHeight) + canvas.drawBitmap(originalBitmap, srcRect, destRect, null) + } + if (originalHeight > processedHeight) { + val srcRect = Rect(0, processedHeight, processedWidth, originalHeight) + val destRect = Rect(0, processedHeight, processedWidth, originalHeight) + canvas.drawBitmap(originalBitmap, srcRect, destRect, null) + } + } + + originalBitmap.recycle() + + val outputStream = ByteArrayOutputStream() + descrambledBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream) + descrambledBitmap.recycle() + + return outputStream.toByteArray().toResponseBody("image/jpeg".toMediaType()) + } +}